Can someone post their working validation example? Actually, I have it all working, EXCEPT for the extra parent level messages of "Tasks is invalid" (in my case not Tasks, but you get the idea.) I don't want these messages since I have the correct task error messages following the main project messages.
I know some others earlier in this thread have mentioned the same thing, but I'm looking for what people have done about it. Does someone have a snippet of code that shows the best way to handle this? I would think it would just involve iterating over the errors and removing the messages I don't want? I'd like to see the best way to handle this, though.
I had two different railscasts tabs open and posted my previous comment in the wrong one (it was meant for http://railscasts.com/episodes/75-complex-forms-part-3). Please delete it if possible. Once again, sorry.
Can someone post their working validation example? Actually, I have it all working, EXCEPT for the extra parent level messages of "Tasks is invalid" (in my case not Tasks, but you get the idea.)
I know some others earlier in this thread have mentioned the same thing, but I'm looking for what people have done about it. Does someone have a snippet of code that shows the best way to handle this? I would think it would just involve iterating over the errors and removing the messages I don't want? I'd like to see the best way to handle this, though.
Ryan,
Why not just move the helper methods that were public into private static methods at the bottom of your file. Then it is clearer to the coder and they do not have to go look at another file.
Thanks for the great tutorial. I'm new to Rails and loving it.
I'm currently working on a form that requires creating 3 models where each belongs_to the previous. Can I use the same technique to go more than 2 levels deep? For example, instead of just being able to create a Project and it's associated Tasks on the same form, can I do something like create a Category, Project, and Task on one form? Not sure exactly how fields_for works.
wow I was just learning about liquid last night. what an awesome coincidence you posted this episode this week. I love these screen casts. I always learn little tricks that I take with me everywhere.
Nice screencast. But I was waiting all the time for one small note: Before rendering a different HTML layout, everyone should check, if they can modify the layout just by css. If your layout is from this century, that should be enough in 99% of the cases.
Ryan, awesome podcast! I've created a few helpful rake tasks to help out with using Passenger in development that those interested in this subject may want to look at:
@Paul, from my understanding, the layout is global state, and setting global state directly in a request is a bad thing to do since this is shared between threads. Setting it in one thread will effect another.
Great screencast. I'm just wondering what makes the original code NOT thread safe, and what makes the new code thread safe. That would be very helpful in writing better thread safe code.
@Jonathan, it will call set_layout for every action, but it checks for the existence of @current_blog which is only set for the show action. In a sense it's doing the same thing.
I haven't had a chance to fully test this yet, so I'll play around with it to make sure it works properly. But in theory it should.
I'm not sure what happens if you now call "layout" in another controller - does it override this :set_layout? Gotta try that.
Q1 - Overall Ryan/guys would you recommend RSpec for controller & model testing over Rails tests? (just want to jump in with one of them)
Q2 - Can I assume that the core testing framework (e.g. rails unit testing versus RSpec) is a kind of separate issue to whether you using mocking or not? i.e. you could use Mocha with either the rails unit test framework or Rspec? Or is there something in Rspec that integrates moreso with mocking?
The thread safe code now loads the layout for every action, not just show. Why not just leave the dynamic layout code in the blog_controller now? Anyway, with 2.2 approaching fast, there will be a lot of code needing modification to make it thread safe, maybe a screen cast about it?
@Pratik, thanks for the correction. I'll mention it in the show notes. Since Rails is becoming thread safe I have to pay more attention to this kind of thing!
Hi Ryan,
first of all 'Thank you for these amazing screencasts'!
You asking for alternatives in one of the previous posts. Have you heard from HAML http://haml.hamptoncatlin.com/ ? Is it an alternativ to Liquid for you? In my opinion it has some interesting approachs.
@jeff, @kenny, @erik
I had similar problems that you describe in your posts.
I found that I makes a difference whether you install it as a plugin (from github) or a gem. With the gem I could not get the route to accept the :subdomain-condition correctly. But then I installed the plugin with
./script/plugin install...
and all of a sudden it worked fine.
I'm workin on a debian-linux-machine (4.0) with Rails 2.1.0 if that is any help. I have no idea how this works on other setups. ;)
PS: don't forget the initializer-script for local development mode to set the number of tlds right.
@ryan: very nice screencast - I love your work. Thank you.
@greg there is an alternative podcast feed in iTunes -- follow the itunes link at top of page, then look for 'Railscasts (iPod + Apple TV)' in "Also Subscribed To"
@AC, thanks for the feedback. I try to get variety in the episodes. Some will be basic, others advanced. While this episode doesn't show any new techniques, it combines several techniques shown in previous episodes which I think will be valuable to some. I have a few ideas for more advanced episodes in the near future, stay tuned. :)
Thanks, Ryan. For me, all your screencasts have been perfectly timed. And your casts always use the 'best practices' for smaller things (which others ignore sometimes) like the proxy.pac for the subdomain cast; using liquid (for security) for the templates; the active resource screencasts. I love each and every one of them and find them to be the best way to show my team how to do things the right way.
I really love your screencasts - they've been very helpful to me, so thanks a lot for your effort!
I must say though, I was disappointed to see how basic this episode was. I know, that not all your viewers are advanced, but this really wasn't very creative :/ No offense, but a beginner would've done this without much effort, or research..
I'll be waiting impatiently for the next episode hoping it will be as exciting as some of your previous ones (the advanced forms come to mind :)
Cheers!
PS. Perhaps some of your viewers would be interested in hearing about the redhillonrails plugins (http://redhillonrails.org/) - I've been using Foreign Key Associations, Foreign Key Migrations, Redhillonrails Core, Schema Validations and Transactional Migrations ever since and they've saved me a LOT of time and effort, DRYing my code and ensuring that it works properly. The guys at Redhill have done a tremendous job and released the code for all of us to benefit from - big kudos to them!
@Jeremy, that's a good question, and I'm not sure if the layout method prevents this either. Even if it does I think it's best to ensure this in our application with a validation.
It is so cool to see how easy it is to get a significant feature into a Rails app. Thanks!
One question: what are the security issues involved with letting the user pick her own layout? It would be unfortunate if something like "../../../etc/" were allowed. Is it up to us to prevent this? I can't tell from the "layout" method itself.
Besides just being uber cool, and super easy, I found one OUTSTANDING bonus for me. I no longer have to deploy an app just to see how it looks in IE (since I develop on FF on a Mac).
Now, I can just point my Windows computer to my dev computer's IP address, and Bam! there is the app, as rendered on any OS or browser I have set up. That is a real time saver in CSS development. I'm sure there are other ways of being able to see a development app in multi platforms/os's/browsers, but I have not found any, and this one works like a charm.
That was what i was looking for, where I have one problem to enhance it a little bit for some dynamic usage with radio buttons.
I use a different model, but to make it easier to understand it I'll use the task and project model to explain my problem.
I use select instead of a text_field in _task.erb, which works. But the database query should depend on a radio button where I ask which type should be used.
The reason for that is that a task database entry uses two fields to point to two other tables.
The dynamic part is to use either (tasklow_id and p.tasklow.title) or (taskhigh_id and p.taskhigh.title). While defaulting to tasklow.
Btw, one of tasklow_id or taskhigh_id is NULL and the other one has a value.
Refactoring the select code to a partial could be a way to go and use onclick for the radio button, but I have no idea how to avoid getting many select fields and how to get the initial select box since the onclick works only onclick.
I would really like to see a screencast covering those methods but with a has_many :through, cleaning associated records and then rebuild them in a callback would be an example.
How do you make this kind of thing drop the :conditions => conditions thing in the case that the user doesn't fill in any of the form. Actually, what I'm really doing is adding GeoKit in here, so I want to do a search which uses the :origin => and :within => stuff. It works fine as long as somebody searches using the conditions, but if you search JUST with origin and within, it throws a syntax error because of an AND with nothing in front of it.
Very interesting screencast.
However after viewing it I have more questions ;)
You set up the blog as the subdomain and then in your controller you call something like @blog.posts.find(:id) in order to have only the posts associated with the blog. This is fine when you have few models and not really deep. But how would you do this if you have say comments on your articles? Checking if one comment belong to the blog is a bit more complicated. And if you can comment on the other's people comment, then it become really messy.
How would you do such a thing? I can't find a satisfying solution.
I was having issues when trying to use the route in the screencast:
:conditions => { :subdomain => /.+/ }
This was not working for me when trying to hit the site using www.domain.com. "www" is ignored by default in subdomain_fu, but this condition seemed to treat the "www" like it was a true subdomain. The route I'm now using has this condition:
@Marc, I tried MPlayer from the command line and it works fine. I guess I need to figure out what's different between clicking on an icon vs. running the program from the command line. Thanks for the clue.
Can someone post their working validation example? Actually, I have it all working, EXCEPT for the extra parent level messages of "Tasks is invalid" (in my case not Tasks, but you get the idea.) I don't want these messages since I have the correct task error messages following the main project messages.
I know some others earlier in this thread have mentioned the same thing, but I'm looking for what people have done about it. Does someone have a snippet of code that shows the best way to handle this? I would think it would just involve iterating over the errors and removing the messages I don't want? I'd like to see the best way to handle this, though.
Oooops! I'm embarrassed.
I had two different railscasts tabs open and posted my previous comment in the wrong one (it was meant for http://railscasts.com/episodes/75-complex-forms-part-3). Please delete it if possible. Once again, sorry.
Can someone post their working validation example? Actually, I have it all working, EXCEPT for the extra parent level messages of "Tasks is invalid" (in my case not Tasks, but you get the idea.)
I know some others earlier in this thread have mentioned the same thing, but I'm looking for what people have done about it. Does someone have a snippet of code that shows the best way to handle this? I would think it would just involve iterating over the errors and removing the messages I don't want? I'd like to see the best way to handle this, though.
This is so easy, it's great! Thanks for the walkthrough.
I was having trouble using this with code in the form:@user=User.new(params[:user]) because AFAIK #new will only use column names.
In the end I opted for:
@user = Jammer.new(params[:user])
@user.my_virtual_att = params[:user][: my_virtual_att]
which is working fine.
thanks for the explanation.
@kino check out
http://www.gitcasts.com/
Ryan,
Why not just move the helper methods that were public into private static methods at the bottom of your file. Then it is clearer to the coder and they do not have to go look at another file.
Regarding the stack errors -
The official ticket is at
http://dev.rubyonrails.org/ticket/10896
and the solution that worked best for me (since I'm not using mem_cached) was -
change line 244 of "attribute_methods.rb" to read
if false and self.class.primary_key.to_s == method_name
Thanks for the great tutorial. I'm new to Rails and loving it.
I'm currently working on a form that requires creating 3 models where each belongs_to the previous. Can I use the same technique to go more than 2 levels deep? For example, instead of just being able to create a Project and it's associated Tasks on the same form, can I do something like create a Category, Project, and Task on one form? Not sure exactly how fields_for works.
Awesome! I'm a little late to the ROR party, but your Railscasts help me to improve every day. Keep up the great work!
wow I was just learning about liquid last night. what an awesome coincidence you posted this episode this week. I love these screen casts. I always learn little tricks that I take with me everywhere.
Thanks Sean!! that fixed it for me too.
Nice screencast. But I was waiting all the time for one small note: Before rendering a different HTML layout, everyone should check, if they can modify the layout just by css. If your layout is from this century, that should be enough in 99% of the cases.
Using transpose for top-down layout:
<% n = 3 %>
<% a.in_groups_of((a.length/n).ceil).transpose.each do |row| %>
taken from
http://ruby-on-the-interrails.blogspot.com/2008/09/method-of-day-arrayingroupsof.html
@keyJ,
I have tried both the gem and the plugin install, as I suspected that the problem was as you describe.. Still can't get it to work though..
Ryan, awesome podcast! I've created a few helpful rake tasks to help out with using Passenger in development that those interested in this subject may want to look at:
http://github.com/qrush/attendant/tree/master
@Paul, from my understanding, the layout is global state, and setting global state directly in a request is a bad thing to do since this is shared between threads. Setting it in one thread will effect another.
Someone please correct me if I'm wrong.
Hi Ryan,
Great screencast. I'm just wondering what makes the original code NOT thread safe, and what makes the new code thread safe. That would be very helpful in writing better thread safe code.
Thanks,
Paul
@Jonathan, it will call set_layout for every action, but it checks for the existence of @current_blog which is only set for the show action. In a sense it's doing the same thing.
I haven't had a chance to fully test this yet, so I'll play around with it to make sure it works properly. But in theory it should.
I'm not sure what happens if you now call "layout" in another controller - does it override this :set_layout? Gotta try that.
Q1 - Overall Ryan/guys would you recommend RSpec for controller & model testing over Rails tests? (just want to jump in with one of them)
Q2 - Can I assume that the core testing framework (e.g. rails unit testing versus RSpec) is a kind of separate issue to whether you using mocking or not? i.e. you could use Mocha with either the rails unit test framework or Rspec? Or is there something in Rspec that integrates moreso with mocking?
Hi,
Where does the "build" method come from? I looked in Mocha, Ruby, Rails APIs methods but could not find it?
Thanks
The thread safe code now loads the layout for every action, not just show. Why not just leave the dynamic layout code in the blog_controller now? Anyway, with 2.2 approaching fast, there will be a lot of code needing modification to make it thread safe, maybe a screen cast about it?
@Werbeagentur,
Sorry! I misunderstood your question! I had the same problem actually. What does your HTML look like for your "states" in your form?
@Werbeagentur,
Try http://localhost:3000/javascripts/dynamic_states.js
@Pratik, thanks for the correction. I'll mention it in the show notes. Since Rails is becoming thread safe I have to pay more attention to this kind of thing!
Hi Ryan,
first of all 'Thank you for these amazing screencasts'!
You asking for alternatives in one of the previous posts. Have you heard from HAML http://haml.hamptoncatlin.com/ ? Is it an alternativ to Liquid for you? In my opinion it has some interesting approachs.
@jeff, @kenny, @erik
I had similar problems that you describe in your posts.
I found that I makes a difference whether you install it as a plugin (from github) or a gem. With the gem I could not get the route to accept the :subdomain-condition correctly. But then I installed the plugin with
./script/plugin install...
and all of a sudden it worked fine.
I'm workin on a debian-linux-machine (4.0) with Rails 2.1.0 if that is any help. I have no idea how this works on other setups. ;)
PS: don't forget the initializer-script for local development mode to set the number of tlds right.
@ryan: very nice screencast - I love your work. Thank you.
This is exactly the kind of programming we'd want to avoid for thread safety reasons. Better way would be http://pastie.org/264443
@greg there is an alternative podcast feed in iTunes -- follow the itunes link at top of page, then look for 'Railscasts (iPod + Apple TV)' in "Also Subscribed To"
@AC, thanks for the feedback. I try to get variety in the episodes. Some will be basic, others advanced. While this episode doesn't show any new techniques, it combines several techniques shown in previous episodes which I think will be valuable to some. I have a few ideas for more advanced episodes in the near future, stay tuned. :)
Thanks, Ryan. For me, all your screencasts have been perfectly timed. And your casts always use the 'best practices' for smaller things (which others ignore sometimes) like the proxy.pac for the subdomain cast; using liquid (for security) for the templates; the active resource screencasts. I love each and every one of them and find them to be the best way to show my team how to do things the right way.
Justin,
I am having the same problem suddenly. It seems related to using ruby enterprise instead of normal ruby. It's the only thing I've recently changed.
Anyone else notice it being related to Ruby Enterprise?
Hi Ryan.
I really love your screencasts - they've been very helpful to me, so thanks a lot for your effort!
I must say though, I was disappointed to see how basic this episode was. I know, that not all your viewers are advanced, but this really wasn't very creative :/ No offense, but a beginner would've done this without much effort, or research..
I'll be waiting impatiently for the next episode hoping it will be as exciting as some of your previous ones (the advanced forms come to mind :)
Cheers!
PS. Perhaps some of your viewers would be interested in hearing about the redhillonrails plugins (http://redhillonrails.org/) - I've been using Foreign Key Associations, Foreign Key Migrations, Redhillonrails Core, Schema Validations and Transactional Migrations ever since and they've saved me a LOT of time and effort, DRYing my code and ensuring that it works properly. The guys at Redhill have done a tremendous job and released the code for all of us to benefit from - big kudos to them!
Wow, very handy. Thanks again Ryan!
@Jeremy, that's a good question, and I'm not sure if the layout method prevents this either. Even if it does I think it's best to ensure this in our application with a validation.
# blog.rb
validates_format_of :layout_name, :with => /^[a-z]+$/i
It is so cool to see how easy it is to get a significant feature into a Rails app. Thanks!
One question: what are the security issues involved with letting the user pick her own layout? It would be unfortunate if something like "../../../etc/" were allowed. Is it up to us to prevent this? I can't tell from the "layout" method itself.
Brilliant! Your timing couldn't have been better..
Great cast again, so helpful, i dont think i would have leant so much in the past year without your help.
Much appreciated!
Besides just being uber cool, and super easy, I found one OUTSTANDING bonus for me. I no longer have to deploy an app just to see how it looks in IE (since I develop on FF on a Mac).
Now, I can just point my Windows computer to my dev computer's IP address, and Bam! there is the app, as rendered on any OS or browser I have set up. That is a real time saver in CSS development. I'm sure there are other ways of being able to see a development app in multi platforms/os's/browsers, but I have not found any, and this one works like a charm.
Thanks for the excellent screencast!
Thank you Ryan for your casts.
That was what i was looking for, where I have one problem to enhance it a little bit for some dynamic usage with radio buttons.
I use a different model, but to make it easier to understand it I'll use the task and project model to explain my problem.
I use select instead of a text_field in _task.erb, which works. But the database query should depend on a radio button where I ask which type should be used.
The reason for that is that a task database entry uses two fields to point to two other tables.
Here is the _task.erb code which I try to use:
<tr class="task">
<% fields_for_task(task) do |task_form| %>
<td id="radio">
Task Low<%= radio_button_tag('type', 0, checked = true) %><br>
Task High<%= radio_button_tag('type', 1, checked = false) %>
</td>
<td id="select">
<%= task_form.select :todo_id, Todo.find(:all, :conditions => "tasklow_id is not NULL").collect {|p| [ "#{p.tasklow.title}", p.id ] }, { :include_blank => true } %>
</td>
<td><%= link_to_function "remove", "$(this).up('.slot').remove()" %></td>
<% end %>
</tr>
The dynamic part is to use either (tasklow_id and p.tasklow.title) or (taskhigh_id and p.taskhigh.title). While defaulting to tasklow.
Btw, one of tasklow_id or taskhigh_id is NULL and the other one has a value.
Refactoring the select code to a partial could be a way to go and use onclick for the radio button, but I have no idea how to avoid getting many select fields and how to get the initial select box since the onclick works only onclick.
I would really like to see a screencast covering those methods but with a has_many :through, cleaning associated records and then rebuild them in a callback would be an example.
Excellent. I've been searching for this for a long time. Thanks, Ryan!
Works fine in iTunes on my Mac, but won't download to my iPhone 3G. No doubt someone has commented on this under another podcast.
These podcasts are great. Thanks.
Very usefull cast. I will add subdomains in my new application.
I hope someone can help me.
I don't want to use the nifty scaffolding approach. What does it generate in the new and show methods?
Thanks.
I'd love to see how to make a gem plugin, similar to how you made a normal plugin in episode 33!
How do you make this kind of thing drop the :conditions => conditions thing in the case that the user doesn't fill in any of the form. Actually, what I'm really doing is adding GeoKit in here, so I want to do a search which uses the :origin => and :within => stuff. It works fine as long as somebody searches using the conditions, but if you search JUST with origin and within, it throws a syntax error because of an AND with nothing in front of it.
Very interesting screencast.
However after viewing it I have more questions ;)
You set up the blog as the subdomain and then in your controller you call something like @blog.posts.find(:id) in order to have only the posts associated with the blog. This is fine when you have few models and not really deep. But how would you do this if you have say comments on your articles? Checking if one comment belong to the blog is a bit more complicated. And if you can comment on the other's people comment, then it become really messy.
How would you do such a thing? I can't find a satisfying solution.
I was having issues when trying to use the route in the screencast:
:conditions => { :subdomain => /.+/ }
This was not working for me when trying to hit the site using www.domain.com. "www" is ignored by default in subdomain_fu, but this condition seemed to treat the "www" like it was a true subdomain. The route I'm now using has this condition:
:conditions => { :subdomain => true }
This seems to work as expected with "www".
@Marc, I tried MPlayer from the command line and it works fine. I guess I need to figure out what's different between clicking on an icon vs. running the program from the command line. Thanks for the clue.