I am getting nil values for :sender in the invitation model when trying to create an invite.
It seems like there's something wrong with my relationship between the user and invitation models, even though I copied your relationships in the screencast.
Wow. This topic has a lot of comments. I started reading through them to look for an answer to my question, but I didn't make it very far.
My question is this: is there a way to clear up any confusion from using multiple attributes of the child objects? I now see the last comment (#121) from Rustin is somewhat along these lines. If I wanted to set the task name as well as whether it should be active or not, the params sent back to my controller might look something like:
Well, technically pluralize() is available through ActiveSupport today, though it doesn't switch strategies based on a count. That's pretty easy to add though:
I tried using session singular when using script/generate but I ran into problems. I undid that and used plural sessions as recommended in the README. I still got the uninitialized constant error but that got resolved when I pluralized session in defining the login and logout routes.
@James
user is a notion that exist only in the context of a request, therefore it is within controller scope.
To observe a model in this context you have to use a sweeper.
For audit trails use the fantastic acts_as_audited plugin
http://github.com/collectiveidea/acts_as_audited/tree/master
You will find the exact scenario of logging user action on models.
Another technique I used is to introduce instance variables on
retrieved model objects and assign current_user or action to them in the controller. This captures the idea that this is not the peristent object, but the object manipulated via an interface.
Once that is done, you can even implement audit or access control within the model class via callbacks and validations, respectively. Some of your validations can be conditioned on on whether these 'controller-related' instance variables are nonnil. If nonnil, then the model is manipulated via a controller (rather than, say a daemon/script/console).
I've started naming my initializer "_site.rb". The initializers are loaded alphabetically, and you want this one to be first, if you ever use the configuration values in other initializers (e.g. initializers/mail.rb for mailer settings).
I have never seen that @template variable before. Never knew you could do that. Hopefully that will help when trying to render a link_to_remote inside a controller. I have pretty much quit a project cause I couldn't get it to work.
thank you for the nice screencast. i've enabled memcache on 2 high-traffic projects with many db querys and it enhance the speed of these sites conspicuously.
@Ryan-
Is there a way to access the "current_user" from the model and/or from an observer? Or is that just a terrible practice? I find I'm often wanting to get the current_user's id in various models, and ALWAYS need it for event observers (where an event is logging the who, what, when of an action).
When using params with the redirect_to method be aware of the security implications. Check out my blog post and the "Response Splitting" post in the Rails weblog.
Interesting stuff. However, there's a good reason why you have to jump through hoops to use helper methods in non-view code: because helper methods are for presentation. MVC and all that. That may be a worthwhile tradeoff, but it's important to keep in mind.
@Ben, interesting, link_to does not work directly in a controller for me. What version of Rails are you using? And have you installed any additional plugins which might enable this?
Observers, like models, exist outside the scope of the current request. Perhaps you need a sweeper instead? That's like an observer but has access to URL helpers and other request related things.
@Per Velschow, good point. I could see the pluralize helper method being moved into ActiveSupport, but the interface would likely need to change (maybe being callable on integer or string) and I'm not entirely certain these kind of methods really belong on those classes.
But until that happens, I'm okay with referencing ActionController::Base in a model if it's simply to get the helper methods that work well in a model. Unless of course you're building a gem of some kind that needs to be used outside of the traditional Rails structure.
Being a bit cheeky one could argue that if a helper method is useful and safe to use outside of ActionView, then it should probably be refactored out into its own module - perhaps ActiveSupport.
Seeing ActionView or ActionController in the model code should generally make you shiver, I think. :)
I'm running into a weird problem I can't seem to figure out. I've got the code from the book working per se. However, no matter how many new attribute fields I add via the RJS link (in my case, it is "Add Another Child"), only the child entered into the original fields (i.e.: the first Child/Task field presented on load) is sent back to the controller. None of the rest are sent. If you click "Delete" and delete all the fields, then add one more back, the data in that new field isn't saved either, so it seems that for some reason only the original field is saved.
Strangely, after inspecting the generated source, it all looks fine and as if it has been compiled correctly. The HTML generated by the original view (with the initial child/task) is identical to the HTML generated when you delete the first child/task field and immediately add another one back, yet the latter doesn't send anything back to the controller.
for some reason I'm getting the following routes-related error: formatted_piece_url failed to generate from {:controller=>"piece", :action=>"show", :id=>:js}, expected: {:controller=>"piece", :action=>"show"}, diff: {:id=>:js}
Any idea why it keeps wanting to use the show action? I can't seem to figure how to get the route to go to the index action. My code here is just formatted_piece_url(:js). Can't seem to get this working until the routes are working, but everything else from the video is working fine! Any help?
great episode. I have a question that has actually come up in certain other episodes. I understand the difference between class and instance methods. But I dont understand why in the setter method of invitation_token= you set
self.invitation=Invitation.find_by_token(token)
why is it the class variable there as in self.invitation, isn't each invitation a separate instance?
Thank you!
(I am looking at around the 16:24 minute mark of this video)
I'm having problems with the code in this line: "attributes = task_attributes[task.id.to_s]". I Keep getting the error "can't convert String into Integer" if I take out the to_s method it goes away, but the existing tasks get deleted. Anyone ideas why?
Ryan, thank you so much for this screen cast. It helped me a great deal! I'm very happy with thinking_sphinx in my current fresh app, however, I plugged it into an old project and it overwrote the destroy methods of most activerecord objects, so I couldn't delete anything. Instead it threw a missing method error, for 'quoted_table_name'
I'm using your plugin to disable validation on the backend side of our application. it works fine. but with validation enabled on the frontend side i get SystemStackError: stack level too deep Error.
there are 4 models involved in the transaction using all of belongs_to, has_many :through as well as :polymorphic
We've been using God (0.7.8) to monitor a couple applications all running on Thin. The awesome bit with God is that it brings process back almost instantly. For example if we request a restart (thin -C path/to/config restart) it will usually catch the fact that they went down and bring them back up before Thin can finish the restart. This is an order of magnitude faster than we were seeing with Monit.
The only issue we've had so far with God is that it appears to have a memory leak (using Ruby 1.8.6-p114). Every now and again we'll notice it's running with 3g of virtual memory and taking up 100% processor. We've been able to solve this though by restarting god nightly (hooray cron).
We have played with the idea of having Monit monitor God but haven't gotten around to actually trying it.
I'm unable to stop or restart the daemon. Anyone figure out how to fix this?
The log file also has this:
#<NoMemoryError: failed to allocate memory>
#<SystemStackError: stack level too deep>
#<fatal: exception reentered>
#<Errno::ENOENT: No such file or directory - /home/sthapit/workspace/rezz/log/mailer.rb.pid>
I am getting nil values for :sender in the invitation model when trying to create an invite.
It seems like there's something wrong with my relationship between the user and invitation models, even though I copied your relationships in the screencast.
Anyone else having this same issue?
Please help!
thanks in advance
This is a really nice screencast. Testing should be pushed more and more. To many projects fail due to poor testing. Many thanks!
Wow. This topic has a lot of comments. I started reading through them to look for an answer to my question, but I didn't make it very far.
My question is this: is there a way to clear up any confusion from using multiple attributes of the child objects? I now see the last comment (#121) from Rustin is somewhat along these lines. If I wanted to set the task name as well as whether it should be active or not, the params sent back to my controller might look something like:
{"project":
{"name": "my project",
"tasks":
[ {"name": "foo"},
{"name": "bar"},
{"active": "t", "name": "blah"},
{"active": "f"},
{"active": "t"} ]
}
}
Which is not very useful. Advice?
I'm having the same problem as Ryan S. -- I get .rss appended to links coming out of my RSS feed. Has anyone figured this out?
Well, technically pluralize() is available through ActiveSupport today, though it doesn't switch strategies based on a count. That's pretty easy to add though:
"product".send(products.count != 1 ? :pluralize : :to_s)
I second that #13. I have yet to find anything on how to use liquid tags. Anyone out there that has a clue?
I tried using session singular when using script/generate but I ran into problems. I undid that and used plural sessions as recommended in the README. I still got the uninitialized constant error but that got resolved when I pluralized session in defining the login and logout routes.
thanks for the awesome script.. i'm just wondering which one is better compare to using ajax..
Very interesting write up. But its difficult to understand!
Great tutorial, will be needing this soon. Thanks Ryan
Or don't forget the =
def category_name=(name)
If you get the "wrong number of arguments (0 for 1)" Error?
Add * to
def category_name(*name)
and the error will disappear
Thank you Ryan! for your efforts
Erez
Thanks 39. gadi !!!
Very good cast!
Very useful! However, can you use scopes when you have polymorphic associations? The :include method wouldn't work, so is there anything you can do?
@James
user is a notion that exist only in the context of a request, therefore it is within controller scope.
To observe a model in this context you have to use a sweeper.
For audit trails use the fantastic acts_as_audited plugin
http://github.com/collectiveidea/acts_as_audited/tree/master
You will find the exact scenario of logging user action on models.
Another technique I used is to introduce instance variables on
retrieved model objects and assign current_user or action to them in the controller. This captures the idea that this is not the peristent object, but the object manipulated via an interface.
Once that is done, you can even implement audit or access control within the model class via callbacks and validations, respectively. Some of your validations can be conditioned on on whether these 'controller-related' instance variables are nonnil. If nonnil, then the model is manipulated via a controller (rather than, say a daemon/script/console).
I've started naming my initializer "_site.rb". The initializers are loaded alphabetically, and you want this one to be first, if you ever use the configuration values in other initializers (e.g. initializers/mail.rb for mailer settings).
I have never seen that @template variable before. Never knew you could do that. Hopefully that will help when trying to render a link_to_remote inside a controller. I have pretty much quit a project cause I couldn't get it to work.
Thanks again Ryan.
Is there any way to get on the view what is the amount of objects I want to display per page? Thanks!
thank you for the nice screencast. i've enabled memcache on 2 high-traffic projects with many db querys and it enhance the speed of these sites conspicuously.
i think i use it for all projects now ;-)
thanks a lot ryan
Is the 'ActionController::Base.helpers' method only available in 2.1?
We're using Rails 2.0.2 and get a 'method not found' trying to use it.
@Ryan-
Is there a way to access the "current_user" from the model and/or from an observer? Or is that just a terrible practice? I find I'm often wanting to get the current_user's id in various models, and ALWAYS need it for event observers (where an event is logging the who, what, when of an action).
Nice hint. Cheers.
Very, very helpful. Thanks for your time and effort with this. You are a great instructor.
-Louis
Great as always Ryan!
One question: what would you do if you want to use a custom helper from application_helper.rb in a controller or model?
also, view's methods can be deligated:
delegate :number_with_precision, :to => 'ActionController::Base.helpers'
@Ryan: link_to is in actionview's namespace, so w/o extending it's not available in controller
When using params with the redirect_to method be aware of the security implications. Check out my blog post and the "Response Splitting" post in the Rails weblog.
Would be better to have the reference in a class base of our models ??
class BaseModel
def helpers
ActionController::Base.helpers
end
end
class Category < BaseModel
...
or is there a better way ?
Thanks
Interesting stuff. However, there's a good reason why you have to jump through hoops to use helper methods in non-view code: because helper methods are for presentation. MVC and all that. That may be a worthwhile tradeoff, but it's important to keep in mind.
@Ben, interesting, link_to does not work directly in a controller for me. What version of Rails are you using? And have you installed any additional plugins which might enable this?
Observers, like models, exist outside the scope of the current request. Perhaps you need a sweeper instead? That's like an observer but has access to URL helpers and other request related things.
@Per Velschow, good point. I could see the pluralize helper method being moved into ActiveSupport, but the interface would likely need to change (maybe being callable on integer or string) and I'm not entirely certain these kind of methods really belong on those classes.
But until that happens, I'm okay with referencing ActionController::Base in a model if it's simply to get the helper methods that work well in a model. Unless of course you're building a gem of some kind that needs to be used outside of the traditional Rails structure.
Being a bit cheeky one could argue that if a helper method is useful and safe to use outside of ActionView, then it should probably be refactored out into its own module - perhaps ActiveSupport.
Seeing ActionView or ActionController in the model code should generally make you shiver, I think. :)
"url_helpers in classes inside an observer" should be "url_helpers inside an observer" :)
I don't know why, but in my controller, I simply can do this:
flash[:notice] = "Successfully created #{link_to('product', @product)}."
and as far as I know i din't do anything fancy.
But I have another question: What about url_helpers in classes inside an observer? I didn't get it to work...
Ben
I'm running into a weird problem I can't seem to figure out. I've got the code from the book working per se. However, no matter how many new attribute fields I add via the RJS link (in my case, it is "Add Another Child"), only the child entered into the original fields (i.e.: the first Child/Task field presented on load) is sent back to the controller. None of the rest are sent. If you click "Delete" and delete all the fields, then add one more back, the data in that new field isn't saved either, so it seems that for some reason only the original field is saved.
Strangely, after inspecting the generated source, it all looks fine and as if it has been compiled correctly. The HTML generated by the original view (with the initial child/task) is identical to the HTML generated when you delete the first child/task field and immediately add another one back, yet the latter doesn't send anything back to the controller.
Blows my mind, anyone else seen similar problems?
thanks a lot!
Uninstalling and reinstalling rails fixed my problem of the grouping of the dynamic files.
Matt: what version of Rails are you using in your old project? I try to keep TS working for 1.2.6, but every now and then it breaks.
Might be worth continuing this discussion on the google group:
http://groups.google.com/group/thinking-sphinx
Thanks! A simple technique and a great tutorial.
We have to keep in mind that request.env['HTTP_REFERER'] doesn't exist on the test environments in case you're testing the redirect!
for some reason I'm getting the following routes-related error: formatted_piece_url failed to generate from {:controller=>"piece", :action=>"show", :id=>:js}, expected: {:controller=>"piece", :action=>"show"}, diff: {:id=>:js}
Any idea why it keeps wanting to use the show action? I can't seem to figure how to get the route to go to the index action. My code here is just formatted_piece_url(:js). Can't seem to get this working until the routes are working, but everything else from the video is working fine! Any help?
Ok...found what was MY problem...
Note to self: Adapt the code to your liking!
Big thanks @ Ryan for this nice episode again.
Its so nice and kindly learning rails with your screencasts :-)
great episode. I have a question that has actually come up in certain other episodes. I understand the difference between class and instance methods. But I dont understand why in the setter method of invitation_token= you set
self.invitation=Invitation.find_by_token(token)
why is it the class variable there as in self.invitation, isn't each invitation a separate instance?
Thank you!
(I am looking at around the 16:24 minute mark of this video)
I'm having problems with the code in this line: "attributes = task_attributes[task.id.to_s]". I Keep getting the error "can't convert String into Integer" if I take out the to_s method it goes away, but the existing tasks get deleted. Anyone ideas why?
Ryan, thank you so much for this screen cast. It helped me a great deal! I'm very happy with thinking_sphinx in my current fresh app, however, I plugged it into an old project and it overwrote the destroy methods of most activerecord objects, so I couldn't delete anything. Instead it threw a missing method error, for 'quoted_table_name'
Not to easy. But if you read carefully it works
I think I'll choose for not using the session, but have the browser keeping state by appending the continu shopping url to the show cart URL.
@houssem: wtf.
I'm using your plugin to disable validation on the backend side of our application. it works fine. but with validation enabled on the frontend side i get SystemStackError: stack level too deep Error.
there are 4 models involved in the transaction using all of belongs_to, has_many :through as well as :polymorphic
We've been using God (0.7.8) to monitor a couple applications all running on Thin. The awesome bit with God is that it brings process back almost instantly. For example if we request a restart (thin -C path/to/config restart) it will usually catch the fact that they went down and bring them back up before Thin can finish the restart. This is an order of magnitude faster than we were seeing with Monit.
The only issue we've had so far with God is that it appears to have a memory leak (using Ruby 1.8.6-p114). Every now and again we'll notice it's running with 3g of virtual memory and taking up 100% processor. We've been able to solve this though by restarting god nightly (hooray cron).
We have played with the idea of having Monit monitor God but haven't gotten around to actually trying it.
I'm unable to stop or restart the daemon. Anyone figure out how to fix this?
The log file also has this:
#<NoMemoryError: failed to allocate memory>
#<SystemStackError: stack level too deep>
#<fatal: exception reentered>
#<Errno::ENOENT: No such file or directory - /home/sthapit/workspace/rezz/log/mailer.rb.pid>