Zend Framework isn't looking for camel cased actions when using the router - zend-framework

Hi guys im having a spot of bother, hope someone can shed some light on this.
For some strange reason my route comes up saying action does not exist unless i change the camel casing to all lower case for that actions name then it works fine. but then that goes against the naming conventions! and i dont want to make my code sloppy either.
Heres my route:
$FrontController = Zend_Controller_Front::getInstance();
$Router = $FrontController->getRouter();
$Router->addRoute("artistsave",
new Zend_Controller_Router_Route
(
"artist/save-artist",
array(
"controller"=>"artist",
"action" =>"saveArtist"
)
)
);
Now to me this should look in the ArtistController for the action saveArtistsAction, but it doesn't it throws up this error:
Whoops you encountered the below
error. Action "saveartist" does not
exist and was not trapped in __call()
So it appears to have removed my camel casing in the router as the a for Artist is now lower case in the error and if i rename my action to match that, it works!
Any idea's why it is not looking for saveArtist?
I realise I could just rename it to save as it is part of the artist object but now I have found this I would like to understand before coming unstuck some other time in the future.
Thanks in advance to any help :)
No soon as I sent this I figured it out, but I feel others may fall for the same mistake so best to leave this here and tell the solution!
In the router it is still in URL formatting I was meant to use hyphens not camel casing then the framework works it out. so here is my correction/solution:
$Router->addRoute("artistsave",
new Zend_Controller_Router_Route
(
"artist/save-artist",
array(
"controller"=>"artist",
"action" =>"save-artist"
)
)
);
Happy coding :)

The naming conventions specify that your actions should be named all lowercase up to the word "Action".
So the correct way to name actions is:
saveartistsAction()
somethingthatdoessomethingelseAction()

Related

ZF1 is calling unexpected controller

I have controller named
AbcController
, which is in default module. So it's normally called like
somedomain.com/abc
..and everything is dispatched correctly, however in case uf URL
somedomain.com/!abc
OR
somedomain.com/#abc
iƧ's still routed to
AbcController
, question is why ? Or better question is, where exactly is the url param transformed to controller name ? I'm trying to find that few hours by debugger.
Expected behavior: controller not found exception
Current behavior: view !abc/inde.phtml not found
This is completely strange, please point me. Thank you.
Update:
So, after more time I found the reason, why any characters such ! and # are trimmed:
Zend_Controller_Dispatcher_Abstract::_formatName()
function is doing following:
$segment = preg_replace('/[^a-z0-9 ]/', '', $segment);
Question is, how to skip that and to get correct state (not existing controller)
OK, so there isn't clear solution, or at least I didn't find any. Actually I have workaround - using static router to some other action, like "ind" instead of "index". In case of bad character, controller will be matched, but default action not, what will result in requested 404 response.
Issue is in ZF1 itself, as controller names are claned, but action names aren't. Shoulld be both or nothing, I think.

Rails 4 with CanCan: unknown attribute error after including load_and_authorize_resource

I'm working in Rails 4 and have gotten CanCan to work well with instructions from this issue, except for one use case that I think might be relatively common.
I have a Comment model, which has_many :comments, through: :replies for nested comments. All of this is working well, until I add load_and_authorize_resource to my comments controller. The problem seems to stem from a hidden field sending an optional :parent_comment_id attribute to my create action.
I've permitted this attribute via strong parameters:
def comment_params
params.require(:comment).permit(:content, :parent_comment_id, :post_id, :comment_id, :user_id)
end
So that I can create the association if a :parent_comment_id is included:
if comment_params[:parent_comment_id] != nil
Reply.create({:parent_comment_id => comment_params[:parent_comment_id], :comment_id => #comment.id})
end
But once I add load_and_authorize_resource, I get an unknown attribute error for :parent_comment_id. What am I missing?
Solution came to me in my sleep. Here's what I did to solve the problem:
The only reason comment_params wasn't normally having a problem on create, was because I was excluding the extra :parent_comment_id parameter, like this:
#comment = post.comment.create(comment_params.except(:parent_comment_id))
When CanCan used the comment_params method however, it did no such sanitation. Hence, the problem. It would have been messy to add that sanitation to CanCan on a per-controller basis, so I did what I should have done all along and instead of passing the :parent_comment_id inside :comment, I used hidden_field_tag to pass it outside of :comment and accessed it through plain, old params.
I hope this helps someone else who makes a similar mistake!

What are the different ways to configure routes?

If someone is familier with Zend Framewor, they know what routes are and how they affect the system overall. My question is concerned about ways to can configure this routes. I know two ways to configure them, through Bootstrap.php and application.ini.
However, not hiding the fact that, I am pretty much of a learner in Zend Framework myself, I dont know which one is better and which should be preferred over the other.
Moreover, I do not know, if these are only ways available to configure the router?
So, please tell me what are ways through which we can configure router and which method is better over others.
P.S: I have included the two ways I knew as an answer.
Routing is an configuration which doesn't get change at runtime hence its better to put in configuration file separating from code which is dynamic . Define router in Bootstrap.php if your router depends upon some condition which is dynamic in nature .
Since I am attempting this to be as a guide for those like me, I would like to include the two ways I know of.
Application.ini
resources.router.routes.cat.route = "/browse/:catid/:name/"
resources.router.routes.cat.defaults.controller = index
resources.router.routes.cat.defaults.action = browse
Here What you do is,
resources.router.routes.XXX.route Define the name of the route in place of XXX
catid and name are the two paramters that will taken, when you pass the url is such way /browse/1/pc 1 will be assinged to catid and pc to name
Remaining two line defines the default parameter from controller and action, from MVC
Bootstrap.php
$front = Zend_Controller_Front::getInstance();
// Get Router
$router = $front -> getRouter();
$routeBrowse = new Zend_Controller_Router_Route(
'/browse/:catid/:name',
array(
'controller' => 'index',
'action' => 'index'
)
);
$router -> addRoute('browse', $routeBrowse);
I will avoid the explanation, since pretty much is same as before.
However, I am not sure which one is better that the other one. So, those who knows, update my answer.

Enterprise Library Logging tracelistener extension issue with resolving ILogFormatter

I have been sitting with a problem for quite a while now and I just can't seem to find what I'm missing.
I have written a custom trace listener component for Enterprise Library 5.0 for the Logging application block which works but the configured ILogFormatter just won't resolve and so I always end up with the basic string text when it gets handled by my component.
I saw in the enterprise library source code that they use the "Container.ResolvedIfNotNull()" method. It doesn't seem to work for me. I need it to write out a custom formatted string for my component to use. You know, not just the message but the timestamp, machinename, threadId, etc.
Does anyone have any ideas on how to fix this?
Thanks in advance.
Like I've mentioned on this site: http://entlib.codeplex.com/discussions/261749
When you create your CreationExpression in the TraceListener data class make sure you have a flat constructor definition. To put it in other words, don't return:
() => new MyTraceListener(new TraceListenerConfig(..., Container.ResolvedIfNotNull<ILogFormatter>(), ...));
just have it in the constructor of the MyTraceListener:
() => new MyTraceListener(..., Container.ResolvedIfNotNull<ILogFormatter>(), ...);

How do I use add_to in Class::DBI?

I'm trying to use Class::DBI with a simple one parent -> may chidren relationships:
Data::Company->table('Companies');
Data::Company->columns(All => qw/CompanyId Name Url/);
Data::Company->has_many(offers => 'Data::Offer'=>'CompanyId'); # =>'CompanyId'
and
Data::Offer->table('Offers');
Data::Offer->columns(All => qw/OfferId CompanyId MonthlyPrice/);
Data::Offer->has_a(company => 'Data::Company'=>'CompanyId');
I try to add a new record:
my $company = Data::Company->insert({ Name => 'Test', Url => 'http://url' });
my $offer = $company->add_to_offers({ MonthlyPrice => 100 });
But I get:
Can't locate object method "add_to_offers" via package "Data::Company"
I looked at the classical Music::CD example, but I cannot figure out what I am doing wrong.
I agree with Manni, if your package declarations are in the same file, then you need to have the class with the has_a() relationship defined first. Otherwise, if they are in different source files, then the documentation states:
Class::DBI should usually be able to
do the right things, as long as all
classes inherit Class::DBI before
'use'ing any other classes.
As to the three-argument form, you are doing it properly. The third arg for has_many() is the column in the foreign class which is a foreign key to this class. That is, Offer has a CompanyId which points to Company's CompanyId.
Thank you
Well, the issue was actually not my code, but my set up. I realized that this morning after powering on my computer:
* Apache + mod_perl on the server
* SMB mount
When I made changes to several files, not all changes seems to be loaded by mod_perl. Restarting Apache solves the issue. I've actually seen this kind of issue in the past where the client and SMB server's time are out of sync.
The code above works fine with 1 file for each module.
Thank you
I really haven't got much experience with Class:DBI, but I'll give this a shot anyway:
The documentation states that: "the class with the has_a() must be defined earlier than the class with the has_many()".
I cannot find any reference to the way you are using has_a and has_many with three arguments which is always 'CompanyId' in your case.