Ryan,
The comments above regarding thread safety remind me of an issue we've seen lately in various Rails projects. It might make a good screencast: the danger of cached classes in production environment (the default setting in new Rails projects) and application state work-arounds with code like 'User.current_user' or 'Project.current'. Imagine what happens when you forget to nullify that value after each controller action :)
I did this for an HABTM association. The join table records are not getting deleted on removing the child records. Everything else is fine though. So it is just the clutter in the join table that has to be removed. Just wondering if Pascal, pimpmaster or any other managed a solution to that..
@Carl, I'm just running on a 256 MB slice, both here and at slicehost. Both hosts fit my needs equally well since this is such a simple site. Rails Machine offers quite a bit more with their plan so you should look into it and see if it fits your needs.
How do you suggest removing cache for a large number of items and multiple conditions. For example domain.com/:controlller/:action/:id/:season/:collection. This url could leave hundreds of cached files.
I see the docs suggest looping through each item but in my situation this is not reasonable.
I'm at slicehost now and I'm happy with what I get for my $$, but I'm also curious about other providers. Ignoring the price difference (or what it would be if you had to pay for it) how would you compare the two for a production rails app? What kind of slice (size and OS) were you running railscasts on before?
@sthapit I used to use slicehost and had no problems, but Rails Machine was kind enough to host it for free. :)
@Fredd, you'll need to set the counter caches directly. Usually this is possible with a query at the end to count the associated models. I'll look into providing a more convenient way to do this.
@Pascal, the :per_query option will do this, it defaults to 1000 so I may need to lower this. It will vary depending on the size of each record.
what i keep trying to wrap my head around is how does rails/ruby know where all these "hacks" are to compile them into a class. is activerecord a singleton in memory? i just don't get it.
I've copied the code because I'm wanting to use it for my article rss and when I click on the RSS bookmark feed, I get redirected to http://localhost:3000/articles/1.rss with a blank screen. Any ideas?
If I add to many records at the same time, MySQL give me this error through the task:
Mysql::Error: Got a packet bigger than 'max_allowed_packet' bytes
I know that max_allowed_packet is a parameter into MySQL, but do you know if there is a way to tell Populator to insert the records by steps instead of waiting at the end to do a big insert ?
Hello!
Thanks for all this great tuts.
Keep up!
I have question about your data base in this tutorial. How she luck like in the moment of creating nifty_scaffold. Please tell me!
Best regards and thanks again!
Hello,
I am trying to use thinking_sphinx, I saw a screencast on rails, I found it very useful to understand this.
I am having an issue when running 'rake thinking_sphinx:index', I get this message:
rake aborted!
undefined method `define_index' for #<Class:0x56ac908>
I am using windows for this, I have put the files for sphinx under %root\db\sphinx
I have not setup a sphinx.yml file.
I am new to all three 'sphinx', 'thinking_sphinx' and 'ruby on rails' so I am not able to figure out the right way to setup sphinx with thinking_sphinx.
Could you please help me understand this? I believe there is some issue with the shpinx setup.
Nevermind you guys, I have fixed it, it was one silliest bug I have ever hunted down.....the form close tag was misplaced.
The Complex forms series is fabulous.
@Ryan have you crafted any railscast on Message objects with file attachments management associated to them as seperate file_column objects or a different plugin...!!?!
@Tony V: thanks for the reply. Although, i found out that :index has to be passed with the html_options for collection_select and its family of form helpers.
Ref: http://dev.rubyonrails.org/ticket/589
I am getting another error that noone else seems to be getting, oddly enough. i am getting an "ActiveRecord::ReadOnlyRecord" error on the save_tasks method. It is raised because when we do tasks.each, the record is instantiated as a read only. (Ref: http://api.rubyonrails.com/classes/ActiveRecord/ReadOnlyRecord.html). The solution is here - http://learn.theworkinggroup.ca/2007/2/6/activerecord-readonlyrecord-error-what. However, im not sure if its great programming because of the many queries raised. Any work arounds? hope that was helpful for someone.
yourstruly_vinay: I think if you use :index => "" instead of nil, it'll work. A quirk in collection_select.
Now my problem:
I'm in the same boat as glennpow and others in that I'm befuddled by compound model creation: I can get two models to parent correctly as in the screencasts, but if I try to get to a third level, no soap.
My situation:
I have an Invite model that is a proxy for new (mass assignment) User creation:
This works fine, as in Project/Task creation in the screencasts. However, I also want to have a new Group Membership created for each of the (new) Users created in the same transaction (all Invites are scoped to a Group):
I can generate everything fine with two sets of virtual attributes (for the User and the Membership), EXCEPT the (new) User id for the Membership (If I try to hardwire something like :user_id => @invite.users.id, I get an id like '1546789'. I assume this is because I'm not nesting the Membership creation within the User creation within the Invite. Or maybe I'm just being a dopey newbie....
If anyone has successfully done a multi-level, multi-model form, I'd love to see the code.
Thanks for the great screencast, Ryan. I have a question, however, concerning how you would populate a habtm (has_many :through is possible though) association? In your example, Category-to-Products is a one-to-many, but what if you modeled products to be part of many categories? Nesting the two like you have in your example wouldn't work in that case. Maybe you already came across this problem and have a nice solution? :)
Echoe isn't supposed to be a gem dependency, but looks like something is hosed in my gem config. I think I fixed it, so the latest populator version (0.2.4) should work without echoe installed.
Ryan,
These three screencasts really pack a punch! thanks a lot for this series especially. There is one small glitch i am running into though.. hoping someone can point out the cause of the bug..
i have a complex form with fields from 3 models in the edit and new templates. 2 of them work just fine. in the fields from the 3rd model, there is a collection_select field where i get the following error
/!\ FAILSAFE /!\ Tue Sep 09 10:07:52 +0530 2008
Status: 500 Internal Server Error
Conflicting types for parameter containers. Expected an instance of Array but found an instance of Hash. This can be caused by colliding Array and Hash parameters like qs[]=value&qs[key]=value. (The parameters received were {"1"=>{"days"=>"7"}}.)
i have set ':index => nil' in the code.. here is my code for that field
@Ren & @Neil, do a gem install echoe...should install and you'll be good to go. I had the same issue, maybe he doesn't have it requiring it as a dependency upon installation.
@Mina: I've found (what I feel) is a cleaner way to handle the validation issue. I add a dummy project_id in my build call, which is neatly overwritten with the actual project_id when the task is saved. Using the example above:
tasks.build(attributes.merge(:project_id=>999))
This works, assuming task validates :project_id, not :project.
If this makes anyone scream, please let me know. It's just the best workaround I was able to come up with in my current, time-sensitive project.
Wow, I was just thinking about creating some loops to do this very thing to do some sort of stress testing on my slice to see how long different approaches would take. Perfect timing, thanks!
I wrote an article about this a while back (http://railspikes.com/2008/1/25/fuzzing-your-database) but it was a more random approach. I like the approach of using Faker to generate more realistic data.
I never said wildcards were not a good use here (although I personally hate them) but a wildcard A record is safer to use, and more efficient than, a wildcard CNAME. For one, it is only one DNS lookup, where the other can be up to two (if the target of the CNAME is not the same as the parent. e.g., *.example.com CNAME www.example.ORG)
Wildcards in DNS don't often do what people expect. They don't behave like 'regular' wildcards, but as a strange beast at times. As an author of a DNS server (BIND 9) we often get bug reports about them. Use them carefully, is all I say!
That said, this use of them is common, and pretty tame.
I have a doubt regarding caching in instance variables, forgive me if it is stupid.
What if I would need to catch more than 500 records..For example if I need to retreive all the employees of an organization..Would it be fine or is there any other suitable way to maximise performance?
Good work, Ryan. I've done something similar to the "populator" gem on the last on the last few projects I've done, but your interface is much more pleasent, and I'll be using it in the future. Thanks.
Hey @Ryan, I loved the whole complex forms series. I have tried to integrate Saving multiple tasks with a project object in my application which is saving multiple people for a New company object. And it works COOL in Internet Explorer, But I was very disturbed to see there were no params entries under company for company[person_attributes] generated on form submit in Mozilla Firefox 3.
And hence just the company fields got saved, and no record for person associated to that company were saved. Please help me with this weird difference in the Form Submit on an IE page and on a Firefox page.
@madan, I had the same problem with a number of gems. It happens when the library module you're going to use is named differently from the gem. For example if you say
config.gem 'chardet'
=> rake can install the gem, but not unpack it, and rails gives the error
no such file to load -- chardet
and script/about gives the error
These gems that this application depends on are missing:
- chardet
To avoid this, you have to specify the name of the module:
About the custom layout rendering, an easier solution in this case is to use the render method setting the layout param. See it: http://pastie.org/266849
This looks great. Wish I was using version 2.0.
Ryan,
The comments above regarding thread safety remind me of an issue we've seen lately in various Rails projects. It might make a good screencast: the danger of cached classes in production environment (the default setting in new Rails projects) and application state work-arounds with code like 'User.current_user' or 'Project.current'. Imagine what happens when you forget to nullify that value after each controller action :)
Ryan, this is really a great screencast! Thanx for it and keep up the good work!
I did this for an HABTM association. The join table records are not getting deleted on removing the child records. Everything else is fine though. So it is just the clutter in the join table that has to be removed. Just wondering if Pascal, pimpmaster or any other managed a solution to that..
Hi Ryan ,
all goes fine, but the up/down arrow keys were not working in IE when selecting the items in dropdown
thanks
@Carl, I'm just running on a 256 MB slice, both here and at slicehost. Both hosts fit my needs equally well since this is such a simple site. Rails Machine offers quite a bit more with their plan so you should look into it and see if it fits your needs.
How do you suggest removing cache for a large number of items and multiple conditions. For example domain.com/:controlller/:action/:id/:season/:collection. This url could leave hundreds of cached files.
I see the docs suggest looping through each item but in my situation this is not reasonable.
list.shares.each { |share| expire_page(:controller => "lists", :action => "show", :id => share.url_key) }
Thanks for the great screencast!!!!
@Ryan,
I'm at slicehost now and I'm happy with what I get for my $$, but I'm also curious about other providers. Ignoring the price difference (or what it would be if you had to pay for it) how would you compare the two for a production rails app? What kind of slice (size and OS) were you running railscasts on before?
@sthapit I used to use slicehost and had no problems, but Rails Machine was kind enough to host it for free. :)
@Fredd, you'll need to set the counter caches directly. Usually this is possible with a query at the end to count the associated models. I'll look into providing a more convenient way to do this.
@Pascal, the :per_query option will do this, it defaults to 1000 so I may need to lower this. It will vary depending on the size of each record.
@ryan
what i keep trying to wrap my head around is how does rails/ruby know where all these "hacks" are to compile them into a class. is activerecord a singleton in memory? i just don't get it.
I've copied the code because I'm wanting to use it for my article rss and when I click on the RSS bookmark feed, I get redirected to http://localhost:3000/articles/1.rss with a blank screen. Any ideas?
Thanks,
Ryan S
@Pascal: Just had the same problem. There is an option to #populate called :per_query that limits how many records are inserted per query.
Hi
If I add to many records at the same time, MySQL give me this error through the task:
Mysql::Error: Got a packet bigger than 'max_allowed_packet' bytes
I know that max_allowed_packet is a parameter into MySQL, but do you know if there is a way to tell Populator to insert the records by steps instead of waiting at the end to do a big insert ?
Thanks !
Hello!
Thanks for all this great tuts.
Keep up!
I have question about your data base in this tutorial. How she luck like in the moment of creating nifty_scaffold. Please tell me!
Best regards and thanks again!
sthapit: ping it:
PING railscasts.com (75.127.77.214) 56(84) bytes of data.
64 bytes from rm-75-127-77-214.railsmachina.com (75.127.77.214): icmp_seq=1 ttl=47 time=36.2 ms
Great technique, just a question. Is there any support for counter caches?
Hello,
I am trying to use thinking_sphinx, I saw a screencast on rails, I found it very useful to understand this.
I am having an issue when running 'rake thinking_sphinx:index', I get this message:
rake aborted!
undefined method `define_index' for #<Class:0x56ac908>
I am using windows for this, I have put the files for sphinx under %root\db\sphinx
I have not setup a sphinx.yml file.
I am new to all three 'sphinx', 'thinking_sphinx' and 'ruby on rails' so I am not able to figure out the right way to setup sphinx with thinking_sphinx.
Could you please help me understand this? I believe there is some issue with the shpinx setup.
Thank you for your help
-Meka
Nevermind you guys, I have fixed it, it was one silliest bug I have ever hunted down.....the form close tag was misplaced.
The Complex forms series is fabulous.
@Ryan have you crafted any railscast on Message objects with file attachments management associated to them as seperate file_column objects or a different plugin...!!?!
I wish there was any...:)
@Tony V: thanks for the reply. Although, i found out that :index has to be passed with the html_options for collection_select and its family of form helpers.
Ref: http://dev.rubyonrails.org/ticket/589
I am getting another error that noone else seems to be getting, oddly enough. i am getting an "ActiveRecord::ReadOnlyRecord" error on the save_tasks method. It is raised because when we do tasks.each, the record is instantiated as a read only. (Ref: http://api.rubyonrails.com/classes/ActiveRecord/ReadOnlyRecord.html). The solution is here - http://learn.theworkinggroup.ca/2007/2/6/activerecord-readonlyrecord-error-what. However, im not sure if its great programming because of the many queries raised. Any work arounds? hope that was helpful for someone.
On OS X 10.5 you could also add the hostname with the dscl utility (incase your /etc/hosts gets flushed after a reboot).
# Create hostname
dscl localhost -create /Local/Default/Hosts/railscasts.local IPAddress 127.0.0.1
# Delete hostname
dscl localhost -delete /Local/Default/Hosts/railscasts.local
# List hostname(s)
dscl localhost -list /Local/Default/Hosts
* Note: You might need to sudo this :)
@Greg, currently HABTM associations aren't supported by Populator, I'll work on adding that though. Thanks. :)
yourstruly_vinay: I think if you use :index => "" instead of nil, it'll work. A quirk in collection_select.
Now my problem:
I'm in the same boat as glennpow and others in that I'm befuddled by compound model creation: I can get two models to parent correctly as in the screencasts, but if I try to get to a third level, no soap.
My situation:
I have an Invite model that is a proxy for new (mass assignment) User creation:
(invite) has_many => :users
(user) belongs_to => :invite
This works fine, as in Project/Task creation in the screencasts. However, I also want to have a new Group Membership created for each of the (new) Users created in the same transaction (all Invites are scoped to a Group):
(invite) has_many => :memberships
(user/group) has_many :groups/:users, :through => :memberships
(group) has_many :invites
I can generate everything fine with two sets of virtual attributes (for the User and the Membership), EXCEPT the (new) User id for the Membership (If I try to hardwire something like :user_id => @invite.users.id, I get an id like '1546789'. I assume this is because I'm not nesting the Membership creation within the User creation within the Invite. Or maybe I'm just being a dopey newbie....
If anyone has successfully done a multi-level, multi-model form, I'd love to see the code.
Thanks for your ideas.
In finding out how to password the exception_logger interface, I came across this neat stuff:
http://errtheblog.com/posts/67-evil-twin-plugin
Here's my code:
http://gist.github.com/9771
and that's that.
Hope it helps someone.
Thanks for the great screencast, Ryan. I have a question, however, concerning how you would populate a habtm (has_many :through is possible though) association? In your example, Category-to-Products is a one-to-many, but what if you modeled products to be part of many categories? Nesting the two like you have in your example wouldn't work in that case. Maybe you already came across this problem and have a nice solution? :)
Echoe isn't supposed to be a gem dependency, but looks like something is hosed in my gem config. I think I fixed it, so the latest populator version (0.2.4) should work without echoe installed.
One solution for the 302 / forbidden error is to have apache run as your user instead of www
So change:
User www
Group www
to
User myusername
Group myusername
Also adding:
Listen 127.0.0.1:80
is a good security measure, it keeps Apache accessible only to your local machine.
@James
Thanks! Didn't even consider "echoe" to be a gem. It works. Thanks Ryan for an awesome tutorial/gem. Mucho helpful.
Looks nice. I usually do this with a fixture http://pastie.org/268729 , but you'd still need something for really random data... this works well. :)
We have used this in our latest project - but was wondering what SNAFUs, if any throwing in SSL into the mix - anyone has encountered?
Do I need to purchase a wildcard cert?
Ryan,
These three screencasts really pack a punch! thanks a lot for this series especially. There is one small glitch i am running into though.. hoping someone can point out the cause of the bug..
i have a complex form with fields from 3 models in the edit and new templates. 2 of them work just fine. in the fields from the 3rd model, there is a collection_select field where i get the following error
/!\ FAILSAFE /!\ Tue Sep 09 10:07:52 +0530 2008
Status: 500 Internal Server Error
Conflicting types for parameter containers. Expected an instance of Array but found an instance of Hash. This can be caused by colliding Array and Hash parameters like qs[]=value&qs[key]=value. (The parameters received were {"1"=>{"days"=>"7"}}.)
i have set ':index => nil' in the code.. here is my code for that field
<p><label for="frequency">Frequency (in days)</label><br/>
<%= h.collection_select :days, Dates.find(:all), :no_of_days, :no_of_days, :index=>nil %></p>
every other field has ':index => nil' in place and the html code generates fine. any thoughts?
@Ren & @Neil, do a gem install echoe...should install and you'll be good to go. I had the same issue, maybe he doesn't have it requiring it as a dependency upon installation.
The sweepers folder needs to be under the app folder, in case anyone's wondering and doesn't have time to watch the 'cast. Thanks to the authors.
Try putting this in your environment.rb file:
Rails::Initializer.run do |config|
config.gem 'populator'
end
Having the same problem here...
Ren, I have the same problem, and I also believe I installed the gem correctly. Have you updated your rubygems system too?
I'm getting this error:
rake aborted!
Could not find RubyGem echoe (>= 0)
I'm pretty sure I installed the gem properly.
@Mina: I've found (what I feel) is a cleaner way to handle the validation issue. I add a dummy project_id in my build call, which is neatly overwritten with the actual project_id when the task is saved. Using the example above:
tasks.build(attributes.merge(:project_id=>999))
This works, assuming task validates :project_id, not :project.
If this makes anyone scream, please let me know. It's just the best workaround I was able to come up with in my current, time-sensitive project.
Wow, I was just thinking about creating some loops to do this very thing to do some sort of stress testing on my slice to see how long different approaches would take. Perfect timing, thanks!
Cool!
I wrote an article about this a while back (http://railspikes.com/2008/1/25/fuzzing-your-database) but it was a more random approach. I like the approach of using Faker to generate more realistic data.
@Sebastian
I never said wildcards were not a good use here (although I personally hate them) but a wildcard A record is safer to use, and more efficient than, a wildcard CNAME. For one, it is only one DNS lookup, where the other can be up to two (if the target of the CNAME is not the same as the parent. e.g., *.example.com CNAME www.example.ORG)
Wildcards in DNS don't often do what people expect. They don't behave like 'regular' wildcards, but as a strange beast at times. As an author of a DNS server (BIND 9) we often get bug reports about them. Use them carefully, is all I say!
That said, this use of them is common, and pretty tame.
Hi,
I have a doubt regarding caching in instance variables, forgive me if it is stupid.
What if I would need to catch more than 500 records..For example if I need to retreive all the employees of an organization..Would it be fine or is there any other suitable way to maximise performance?
This is great. For the longest time I relied on my spreadsheet data based approach to generating random names as test data.
http://www.markrichman.com/2007/09/26/generating-random-names-as-test-data/
Good work, Ryan. I've done something similar to the "populator" gem on the last on the last few projects I've done, but your interface is much more pleasent, and I'll be using it in the future. Thanks.
Hey @Ryan, I loved the whole complex forms series. I have tried to integrate Saving multiple tasks with a project object in my application which is saving multiple people for a New company object. And it works COOL in Internet Explorer, But I was very disturbed to see there were no params entries under company for company[person_attributes] generated on form submit in Mozilla Firefox 3.
And hence just the company fields got saved, and no record for person associated to that company were saved. Please help me with this weird difference in the Form Submit on an IE page and on a Firefox page.
config.gem "mislav-will_paginate", :lib => "will_paginate"
see http://rails.lighthouseapp.com/projects/8994/tickets/293-gem-dependencies-broken-in-2-1-0
@madan, I had the same problem with a number of gems. It happens when the library module you're going to use is named differently from the gem. For example if you say
config.gem 'chardet'
=> rake can install the gem, but not unpack it, and rails gives the error
no such file to load -- chardet
and script/about gives the error
These gems that this application depends on are missing:
- chardet
To avoid this, you have to specify the name of the module:
config.gem 'chardet', :lib=>'UniversalDetector'
This screencast was very useful. Thank you for doing this!
It is very helpfull
I'm with K. You save the day!
About the custom layout rendering, an easier solution in this case is to use the render method setting the layout param. See it: http://pastie.org/266849