Hi, I'm building a very small site with two models. I'm just going to update it myself so the approach with script/generate scaffold episodes 'admin/episodes' sounds like a fast and easy way to solve it. Now to my question: How do I do the admin page with the links to the two scaffolds. If I have a admin controller it looks for actions in that controller, and if I don't have a admin controller I don't know how/where to make the /admin page...
@Fred, if you look in the API docs you can see form_remote_for is an alias of remote_form_for - so either one will work. While I like the sound of remote_form_for better, I get confused because there's no corrosponding remote_form_tag. There's only form_remote_tag and that parallels better with form_remote_for. So I've got used to using that.
Yes, it's probably possible to do what you are describing. You'd use some of the Scriptaculous visual effects, which Ryan did not cover in this episode. You'd do something like "page[:notice].visual_effect :fade, :duration => 5"
I did not try this. So, I can't verify. But, in theory, you'd do something like that to get the effect you want.
Hey Ryan,
I noticed that you use "form_remote_for". But, the Agile book and the Ajax on Rails book all refer to "remote_form_for". Are they different? Or, is "form_remote_for" an Edge Rails thing?
@Cristiano, I think what you want is an ":if" parameter as I show in the screencast. You would need to create a method to check if the email address is blank. Something like this:
@Ben, the trick is to hold down the "option" key while you make a selection in textmate. This will switch it to column mode and allow you to edit multiple lines at once. After you make a selection you can hit "option" again to toggle back and forth. It's pretty useful. :)
Hey, great job on the screencast. I love watching your tips and tricks. One thing I have a question about though. Not to do with Rails, but rather Textmate. I noticed about 3/4 into the cast, that you selected "map." on two different lines, and then were able to edit both lines simultaneously... My jaw dropped on that one. Could you explain how you did that?
I see the title as view logic. The reason is because if a different controller action renders the same view, it doesn't have to set the title again.
For example, on the "new.rhtml" page you don't want to have to set the title in both the "new" action and the "create" action in the controller (in case the validation fails and the "new.rhtml" view is rendered again).
Now, if the title is complex obviously you don't want to put all that logic in the view. In that case it should be moved into a helper method.
I suppose this is personal preference, but I find placing it in the view is better.
@Karl, sometimes you don't want to only change when a validation takes place, but the logic behind the validation as well. Rails offers various methods for setting validations (such as validates_presence_of), but I don't think there's any for comparing dates. In that case you did the right thing by making it a custom validation in the "validate" method.
I was looking for just something like this yesterday... well, sort of. I need to validate that a :start_date is before the :end_date. I didn't know about the :if => option on validations, so I wrote my own:
def validate
if self.start_date && self.end_date
errors.add( :end_date, "must be after the Start Date") if self.start_date > self.end_date
end
end
Probably not the cleanest method, but i works.
For any Googlers or the curious out there, using this sort of conditional validation allows you to implement a multi-step creation process for a model. However, this sort of thing is VERY difficult to fit into the REST paradigm.
True, the :if condition does take a Proc object, but I never use it because it's kind of ugly. Having it call a method is a much better solution IMO. It is cleaner, it is easier to extend and it can be shared across multiple validations.
I just looked at the Rdoc for validates_presence_of -- I noticed that the :if option can take a proc object. So maybe you could do something like this?
@RSL, this is difficult to find in the documentation. The "save" method defined in ActiveRecord::Base doesn't accept a parameter. However, there is another method called save_with_validation which accepts a boolean. As it turns out, this method overrides the "save" method through alias_method_chain, so that is what is being called.
AFAIK it only applies to the "save" method, not the "create" method or any other method.
I have an additional question about conditional validation:
How do I only check one validation if an other validation returns true? For example, I would like to check the syntax of someones email address and I constructed a nice validator for this, but it doesn't check if the email field exists. Now I would only like to check the validity of the email syntax if the email field is even there. How can I do that?
That last bit about passing false to the save method was really useful-seeming but I can't find anything in the API [official or caboo.se] that verifies that. Can you give a little more information about that? And does it work for create?
This is great! I am a new Mac user and I love that the key combinations flash in the top right as you type. These are great Rails training videos. Thanks
Should controller names be singular (Project) and rather than plural (Projects)?
@Phillip, the named routes generated by map.resources is where the RESTful design is specified as well, so there's no way to separate it. You'll have to create your own named routes if you don't want to use REST. You may want to look into abstracting this into a custom route method (like map.resources) so it's easy to generate the named routes. I'm not sure on the details though.
I don't think there's any issues with caching. You just have to watch out for setting instance variables (like the side sections example). If you cache outside the block, the helper method won't be called every time and the instance variable won't be set.
I, too, enjoy your screencasts. Two questions, one about this episode specifically:
1) is it possible to get the named routing of
map.resources projects
without getting the REST (ha, no pun intended). I'm very new to REST and will have to give some thought to how to handle some actions that I have (such as forgot_password and things like that)
2) what's the chances of the iTunes podcast getting the iPod compatible m4v files? I subscribed to the podcast and was merrily watching on my notebook, but then disappointed when the videos wouldn't go the iPod. I just downloaded all the m4v version manually and imported them into iTunes. I'd like to get the new episodes automatically if I could, which is why I subscribed to the podcast.
Excellent tips, I'll have to implement this soon. One question though...how does the use of blocks in the views work with caching? Does it at all or are there some limitations? Thanks, great screencasts. I look forward to the new ones all the time.
@JEG2, thanks for the suggestion. I've seen the mix of yield and &block in other places as well (such as the source of fields_for) which is one reason I didn't think it mattered. But you know Ruby probably better than any of us here, so I'll try to stick with your suggestion. Thanks! :)
@Alfred, you can prefix the controller name with a forward slash so it goes to the root controller, not the one in the admin module:
link_to 'Projects', :controller => '/projects'
If that doesn't answer your question, I encourage you to post it on railsforum.com.
...I've also tried routing.
map.admin_project 'admin/projects', :controller => 'projects'
But I end up with a error:
NameError in ProjectsController#index
uninitialized constant ProjectsController
Hi, I'm building a very small site with two models. I'm just going to update it myself so the approach with script/generate scaffold episodes 'admin/episodes' sounds like a fast and easy way to solve it. Now to my question: How do I do the admin page with the links to the two scaffolds. If I have a admin controller it looks for actions in that controller, and if I don't have a admin controller I don't know how/where to make the /admin page...
Thanks in advance!
Fantastic! They just keep getting better.
Hi , This will be so usefull.Thank u so much.
This is great, waiting with the validation. When the next part is coming?
Thanks.
Ryan, once again, I just wanted to continue to say good work and thanks for the insight.
Hey Ryan! thanks a lot! So I'll try to build my first helper method! :-)
@maze, yep. You can loop through the flash hash as is done in that episode. For example, place this in the rjs file:
flash.each do |key, msg|
page.replace_html key, msg
end
You may want to move this into a helper method so it can be called from any rjs file.
Great episode!
another useful screencast! Is there a way to combine the update of the flash via AJAX with your screencast 18 (looping through flash)?
ryan,
Ah, that explains it. I never ever look at api docs. haha. . .
@Fred, if you look in the API docs you can see form_remote_for is an alias of remote_form_for - so either one will work. While I like the sound of remote_form_for better, I get confused because there's no corrosponding remote_form_tag. There's only form_remote_tag and that parallels better with form_remote_for. So I've got used to using that.
Michael,
Yes, it's probably possible to do what you are describing. You'd use some of the Scriptaculous visual effects, which Ryan did not cover in this episode. You'd do something like "page[:notice].visual_effect :fade, :duration => 5"
I did not try this. So, I can't verify. But, in theory, you'd do something like that to get the effect you want.
Hey Ryan,
I noticed that you use "form_remote_for". But, the Agile book and the Ajax on Rails book all refer to "remote_form_for". Are they different? Or, is "form_remote_for" an Edge Rails thing?
Great screeencast as always!
put the .rjs somewhere in the views directory. typically the directory where the rest of the views for a specific controller can be found.
Hi, very cool screencast. I was looking for some good ajax advice and now I have it! I have one question though: where did you place the .rjs file?
Hello, Is possible that flash message disappears after 5 seconds?
One of the best screencast.
Nice. Week ago I messed with this. Got many goods tips.
@Cristiano, I think what you want is an ":if" parameter as I show in the screencast. You would need to create a method to check if the email address is blank. Something like this:
--
validates_format_of ..., :if => :email_is_filled
def email_is_filled
!email.blank?
end
--
I don't think validates_format_of takes the allow_nil option, at least I don't see it in the docs.
@Ben, the trick is to hold down the "option" key while you make a selection in textmate. This will switch it to column mode and allow you to edit multiple lines at once. After you make a selection you can hit "option" again to toggle back and forth. It's pretty useful. :)
@Arthur:Geek: Thanx for the tip, but I don't want to allow for a nil, right? Or doesn't that matter because I also do the other check?
Hey, great job on the screencast. I love watching your tips and tricks. One thing I have a question about though. Not to do with Rails, but rather Textmate. I noticed about 3/4 into the cast, that you selected "map." on two different lines, and then were able to edit both lines simultaneously... My jaw dropped on that one. Could you explain how you did that?
I see the title as view logic. The reason is because if a different controller action renders the same view, it doesn't have to set the title again.
For example, on the "new.rhtml" page you don't want to have to set the title in both the "new" action and the "create" action in the controller (in case the validation fails and the "new.rhtml" view is rendered again).
Now, if the title is complex obviously you don't want to put all that logic in the view. In that case it should be moved into a helper method.
I suppose this is personal preference, but I find placing it in the view is better.
太好了,谢谢恁!
I agree with foobar, seting title in view is kind of wrong, logic should go in controller
why dont you set the title in the controller so it can be used by several views?
Thanks again, it is the highlight for the day, when I find a new episode.
Ryan, you are the best!
I was having problem with conditional validations just before you made this episode.
Thanks!
@Karl, sometimes you don't want to only change when a validation takes place, but the logic behind the validation as well. Rails offers various methods for setting validations (such as validates_presence_of), but I don't think there's any for comparing dates. In that case you did the right thing by making it a custom validation in the "validate" method.
I was looking for just something like this yesterday... well, sort of. I need to validate that a :start_date is before the :end_date. I didn't know about the :if => option on validations, so I wrote my own:
def validate
if self.start_date && self.end_date
errors.add( :end_date, "must be after the Start Date") if self.start_date > self.end_date
end
end
Probably not the cleanest method, but i works.
I think this episode was not good, because no real web-browser examples. :-( Only code.
For any Googlers or the curious out there, using this sort of conditional validation allows you to implement a multi-step creation process for a model. However, this sort of thing is VERY difficult to fit into the REST paradigm.
True, the :if condition does take a Proc object, but I never use it because it's kind of ugly. Having it call a method is a much better solution IMO. It is cleaner, it is easier to extend and it can be shared across multiple validations.
Hmm, you might need to pass the user object into the block:
validates_presence_of :password, :if => Proc.new {|user| user.updating_password || user.new_record? }
As always, great stuff!
I just looked at the Rdoc for validates_presence_of -- I noticed that the :if option can take a proc object. So maybe you could do something like this?
validates_presence_of :password,
:if => Proc.new { updating_password || new_record? }
@RSL, this is difficult to find in the documentation. The "save" method defined in ActiveRecord::Base doesn't accept a parameter. However, there is another method called save_with_validation which accepts a boolean. As it turns out, this method overrides the "save" method through alias_method_chain, so that is what is being called.
AFAIK it only applies to the "save" method, not the "create" method or any other method.
The convention is using a plural name for the controller (Projects).
Glad you find the videos useful. :)
This was new for me. It's amazing at how well thought out rails is.
Thanks again for the video Ryan.
Cristiano: Uses the option :allow_nil => true
Eg: validates_format_of :email, :allow_nil => true
I have an additional question about conditional validation:
How do I only check one validation if an other validation returns true? For example, I would like to check the syntax of someones email address and I constructed a nice validator for this, but it doesn't check if the email field exists. Now I would only like to check the validity of the email syntax if the email field is even there. How can I do that?
That last bit about passing false to the save method was really useful-seeming but I can't find anything in the API [official or caboo.se] that verifies that. Can you give a little more information about that? And does it work for create?
This is great! I am a new Mac user and I love that the key combinations flash in the top right as you type. These are great Rails training videos. Thanks
Should controller names be singular (Project) and rather than plural (Projects)?
@Phillip, the named routes generated by map.resources is where the RESTful design is specified as well, so there's no way to separate it. You'll have to create your own named routes if you don't want to use REST. You may want to look into abstracting this into a custom route method (like map.resources) so it's easy to generate the named routes. I'm not sure on the details though.
I don't think there's any issues with caching. You just have to watch out for setting instance variables (like the side sections example). If you cache outside the block, the helper method won't be called every time and the instance variable won't be set.
Nevermind on #2. I just revisited iTunes and see the other podcast.
Thanks!
Phillip
Hi Ryan,
I, too, enjoy your screencasts. Two questions, one about this episode specifically:
1) is it possible to get the named routing of
map.resources projects
without getting the REST (ha, no pun intended). I'm very new to REST and will have to give some thought to how to handle some actions that I have (such as forgot_password and things like that)
2) what's the chances of the iTunes podcast getting the iPod compatible m4v files? I subscribed to the podcast and was merrily watching on my notebook, but then disappointed when the videos wouldn't go the iPod. I just downloaded all the m4v version manually and imported them into iTunes. I'd like to get the new episodes automatically if I could, which is why I subscribed to the podcast.
Thanks for contributing to the Rails community!
Phillip
Excellent tips, I'll have to implement this soon. One question though...how does the use of blocks in the views work with caching? Does it at all or are there some limitations? Thanks, great screencasts. I look forward to the new ones all the time.
@JEG2, thanks for the suggestion. I've seen the mix of yield and &block in other places as well (such as the source of fields_for) which is one reason I didn't think it mattered. But you know Ruby probably better than any of us here, so I'll try to stick with your suggestion. Thanks! :)