RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

It would appear that the FactoryGirl syntax has changed a bit. Instead of

Factory.define :user do |f|
f.sequence(:email) { |n| "foo#{n}@example.com" }
f.password "secret"
end

You now need something more like

FactoryGirl.define do
factory :user do
sequence :email do |n|
"foo#{n}@example.com"
end
password "secret"
end
end

Also then use FactoryGirl.create(:user) instead of Factory(:user)

Avatar

EC2 comes with Elastic Load Balancing, it would be nice to use it instead of a web role.
Is it feasible ?

Avatar

Trying to make it works with mongoid. It doesn't seems to work. Product is always empty. What am I doing wrong?

Anyone using mongoid ?

Avatar

I would love to see some AngularJS too. It seems like the thinnest one, compared to Backbone.js and Knockout.js (although it does not provide a full server like meteor).

Avatar

Ryan,

I think the load_commentable before filter used in this RailsCasts episode is somewhat brittle and, probably too complicated to be used as an example, especially when demonstrating this feature to new users.

I would rather go with a simpler alternative. Something like:

def load_commentable
  @commentable = if params[:article_id]
    Article.find(params[:article_id])
  elsif params[:photo_id]
    Photo.find(params[:photo_id])
  elsif params[:event_id]
    Event.find(params[:event_id])
  end
end

Or even more verbose:

def load_commentable
  if params[:article_id]
    @commentable = Article.find(params[:article_id])
  elsif params[:photo_id]
    @commentable = Photo.find(params[:photo_id])
  elsif params[:event_id]
    @commentable = Event.find(params[:event_id])
  end
end

I see several benefits in this kind of code:

  • Code is less clever, which is a good thing for controller code.

  • Filter code is decoupled from changes to routes. For example, if a scope or namespace was added or the path option was used to produce easier to read routes, you would not need to change filter code or tests.

  • Scopes can be added independently to each find call. Articles could be published and events active, without the need for aliases.

  • Code produces no temporary objects nor relies on string processing which, over time, add up to app execution time.

  • Tests are easier to follow and coverage easier to check.

I would also like to mention that, in real world, some of the most popular uses of polymorphic associations, like comments, are a bad pattern.

In this example, article comments will never be queried as event comments nor -most probably- listed together and, they even might end up having very different requirements. In Ruby, behavior can always be shared using modules.

Still, there are some valid uses for polymorphic associations but, way less than what one would think of first.

P.S. thanks so much for your work and contribution! I admit this is one of the very few cases where I don't agree with the code presented. :-)

Avatar

Excellent episode. I'm looking forward a "part 2" where you would explain how to set up your own templates!
Thanks!

Avatar

After this Railscast I found out that internally Rails is handling the build of the associated object when needed. It seems that this behavior has in fact changed.

The only thing I needed to add is a instantiation of my join model to the action 'new'.

I have a Proposal model which can have many Product through a join model called ProductEntry.

In the action 'new' from my ProposalsController I simply added:

ruby
   @proposal.product_entries << ProductEntry.new

This is just to display the form field when no ProductEntry is available yet, which is always the case when I'm creating a new Proposal.

When I go and edit a Proposal, Rails automatically instantiate all ProductEntry that are associated. If I edit any of those ProductEntry (such as the quantity attribute that I have), it simply works too.

Avatar

Figured it out, key was using the actual join relationship rather than the target of the join, then everything pretty much "just worked"

I won't lie though, this also helped (from a comment on the second part of the complex forms casts) : http://pastie.org/987614

Avatar

What gem was it? I've been having perhaps the same problem and haven't seen any solutions.

Avatar

Unfortunately the official Rails api is misleading when describing how to use url_for and consequently link_to with nested routes. " If you have a nested route, such as admin_workshop_path you’ll have to call that explicitly (it’s impossible for url_for to guess that route)." This isn't the case since you could use url_for([:admin, Workshop.new]) or similar. All you need to do is provide a symbol or an object that's above the target wrapped in an array. Thanks Ryan for pointing this out.

Avatar

Nice example, has anyone tried this with associated tables?
i.e. product table has a category_id
e.g. so the search will result in the searching category.name or product.name...

Avatar

Problem is this format wasn't properly supported in Rails until very recently, and I don't think the fix has actually been released yet.

https://github.com/rails/rails/issues/4127#issuecomment-4167613

Avatar

I don't think so. Unless you only index fields with only a few words such as title. If you want to also index content field, I think you need a dedicated searching software such as sphinx or solr.

Avatar

how does one output a field as a label? I have a user id. A user cannot edit the user id. One way is to set it to disabled, but that doesn't look so nice and gives the impression that it is an editable field.

Avatar

I want to use the factories.rb file exclusively. However, when I run rails generate model User ... I get a spec/factories/user.rb file. How can I configure it so that this does not happen?

Thank you and keep up the great work you're doing with this site.

Avatar

I had the same issue.
I fixed the jquery syntax with this:

ruby
$(link).parent().before(content.replace(regexp, new_id));

instead of the old syntax (prototype I guess)

ruby
$(link).up().insert({  
  before: content.replace(regexp, new_id)
});
Avatar

hello, i was wondering if it was possible to have the drop down display something different from what the user selects? ie in stack overflow, if you type in java, it might display something like 'java x 34' because its count is 34. but when you select it, it just becomes 'java'. is it possible to do it with the jquery token input? ive been reading the documentation and it seems like it only has the :id and :name attribute. i tried doing something like...

tags.map{ |tag| { id: "#{tag.id}", name: "#{tag.name} x #{tag.count}", value: "#{tag.name}" } }

but no success. any ideas?
thanks = )

Avatar

I think he uploaded that image to the gmail account railscasts.example@gmail.com.

Avatar

Ryan: to get the type of commentable tpye and ID, I use the follow code:

def get_commentable
    @commentable = params[:commentable].classify.constantize.find(commentable_id)
end

def commentable_id
  params[(params[:commentable].singularize + "_id").to_sym]
end

and append to the nested comment resource this

, :defaults => { :commentable => 'picture' }

(when commenting on picture)

This way, the only thing you have to remember when adding more commentable is to add the default param to the route and you are done ;-)

Avatar

I just made a gem for dynamically adding has_many association fields, similar to ryan's nested form gem: https://github.com/ncri/nested_form_fields
It allows arbitrarily deep nesting. You are welcome to play with it and send me feedback.

Avatar

Thanks Ryan! And I picked up another text mate tip, CTRL + Shift + H (create partial from template). Actually, do you reckon that could make for a good topic? TextMate tips?

Avatar

polymorphic has_many is much more useful. that way THE SAME photo can belong to many different models.

Avatar

Hi,

I missed the as option to create the helper:

ruby
get "/posts/:id/page/:page", to: 'posts#show', as: post_page
resources :posts

So calling post_page_path(@post, 2) now generated the link /posts/1/page/2 as expected.

But would be great to know how pagination handles that (or if I missed something else in the cast).

Regards,
Hagen

Avatar

Hi,

kind of off-topic, but I try to figure out how to use the route manually without using pagination. Is it pagination figuring out if it has to add the page number as get parameter or as ressource?

ruby
[...]
get "/posts/:id/page/:page", to: 'posts#show'
resources :posts
[...]

I wasn't able to figure out how to make the link_to helper to use of the new route (in this episode it looks like pagination does the "magic"?!).
I don't like hard wired links, so perhaps someone can help me out, I already tried post_url(@post, page: 2), but that leads to the expected /posts/1?page=2 ...

Regards,
Hagen

Avatar

Hi,

no. 2 shouldn't be an issue as long as content is generated via the page itself - the one creating the content will also regenerate the cache :)

Regards,
Hagen

Avatar

If you start psql using this command

'pg_ctl -D /usr/local/var/postgres -l logfile start'

You will be able to run the RVM version just installed. Not sure if this is correct but just worked for me

Avatar

@Sergey Averyanov Do you know what they say about guys who claim to have big guns?

Avatar

Great tutorial as always. I did run into a problem though when trying to implement it into my app. When I add an extra field it didn't show up in the params sent to the controller.

I found the problem was I had put the form into a table and it didn't work well with this. I simply removed the table and it all started to work.

Avatar

Did you get an answer to this? Facing the same issue.

Avatar

if you get the 'value is undefined' it might be because the property it should be searching for isn't set in the tokeninput settings

For instance, if the field that holds the names in your Authors model isn't called names, you need to specify it in the tokenInput option called "propertyToSearch" and change ti to propertyToSearch: "title" (or however you identify your authors)

You'll see it in the configuration settings here.

http://loopj.com/jquery-tokeninput/

Avatar

There is a problem with polymorphic associations if the polymorphic side has Single Table Inheritance: then it will only list the base class as the type.

Avatar

Is this not a good solution due to no foreign key references?

Avatar

thanks i ran into this problem too!! was driving me crazy...

Avatar

Haha, I'm still having a through association issue...see below — any pointers??

Avatar

Quick Q Ryan - the models I'm working with are connecting using has_many :through, and I'm getting issues with creating the sub-objects via the update method, here's the exception:

ActiveRecord::RecordNotFound
Couldn't find Question with ID=1 for Quiz with ID=9

For context, Quizzes have many questions through a join table.

Anyway, decent chance I'll have this fixed before anyone has a chance to reply, but seemed like something enough people might be trying to do to warrant a comment.

Back to figuring it out.. :D

Avatar

I would also like to do the same in an app I am working on at the moment :)

Avatar

I generated a new page and will try to use this as solution. ;)

Avatar

Maybe a strange question but, how would I be able to create for example two pdf files of the same show page?
For example, one pdf file would create an overview and one pdf file would go more into detail, is this possible with prawn?

Many thanks!

Avatar

I second the warning aboiut Searchlogic not working with Rails 3. Took me a while to figure this one out, and I had gotten all excited about using it too :(

It produces this error:

error [long path] 'alias_method': undefined method merge_joins' for classClass' (NameError)

Avatar

For me too. Using Google Chrome 19.0.1084.46 m on Windows 7.

Maybe add a few extra seconds of silence at the end?

Avatar

I got Prawn working, but I keep getting this message in my terminal:

mime_type.rb:102: warning: already initialized constant PDF

Anyone else have this issue?

Avatar

+1 on EmberJS screencast. Different technologies are always welcome!

Avatar

Ryan

How to make a filter for such products?

Avatar

Have you tried using the rescue_from method for this?

Avatar

How would you handle overriding the as_json method for a Polymorphic model?

Once I try to override the query changes to :

... items.type IN ('Api::V1::ProjectsController::Project') ...

Avatar

Yes please! Trying right now to make the decision of backbone or ember.