rails map.resources with has_many :through doesn't work?

后端 未结 3 1508
北恋
北恋 2021-01-03 09:27

I\'ve got three (relevant) models, specified like this:

class User < ActiveRecord::Base
  has_many :posts
  has_many :comments
  has_many :comments_receiv         


        
相关标签:
3条回答
  • 2021-01-03 09:59

    I have to confess, I'm a little confused by the variable names, but first off, I'm surprised your has_many :through works at all the way it's defined. Do the models behave as you expect, setting aside the routes for a second?

    Second, and this is where the variable names really come into play, the routes have some dependencies on pluralization, so your foos bars and bazs might either be a cause of the problem, or might be hiding the problem. In any event, you can definitely write something like this:

    map.resources :users do |user|
      user.resources :awards
      user.resources :contest_entries do |contest_entry|
        contest_entry.resources :awards
      end
    end
    

    which I believe would give you:

    user_path, user_awards_path, user_contest_entry_path, and user_contest_entry_awards_path.
    

    I'm not sure if this really answers your question, and it might help to get a clearer picture of what's going on here if you changed foo, bar, and baz to something closer to the real situation.

    0 讨论(0)
  • 2021-01-03 09:59

    A quick-n-dirty solution would be to add a custom method (e.g. getusercomments) to your users-controller that would return all the comments:

    def getusercomments
    @user = User.find(params[:id])
    @comments = @user.posts.comments
    end
    

    Then add this method to your users-route:

    map.resources :users, :member => { :getusercomments => :get }
    

    Afterwards you should be able to call the following to get all comments of a user:

    http://some_domain.com/users/123/getusercomments
    
    0 讨论(0)
  • 2021-01-03 10:16

    Although the syntax to deinfe resource and model relationship is similar, you shouldn't be fooled into thinking that a resource maps to a model. Read what David Black has to say.

    The problem you're having is with the routes you're generating. Using the nested syntax like so:

    map.resources :users do |user|
      user.resources :posts
      user.resources :comments
      user.resources :comments_received
    end
    

    And then running 'rake routes', gives me (amongst loads of other stuff!):

                           users GET /users                              {:action=>"index", :controller=>"users"}
                      user_posts GET /users/:user_id/posts               {:action=>"index", :controller=>"posts"}
                   user_comments GET /users/:user_id/comments            {:action=>"index", :controller=>"comments"}
    user_comments_received_index GET /users/:user_id/comments_received   {:action=>"index", :controller=>"comments_received"}
    

    So it appears that rails is adding _index to the end of the comments_received route. I'll admit I don't know why (something to do with clashing with the other comments route?) but it explains your problem.

    An nicer alternative might be to define a collection action on your comments resource, like so:

    map.resources :users do |user|
      user.resources :posts
      user.resources :comments, :collection => {:received => :get}
    end
    

    This will give you the following routes:

                     users GET /users                             {:action=>"index", :controller=>"users"}
                user_posts GET /users/:user_id/posts              {:action=>"index", :controller=>"posts"}
             user_comments GET /users/:user_id/comments           {:action=>"index", :controller=>"comments"} 
    received_user_comments GET /users/:user_id/comments/received  {:action=>"received", :controller=>"comments"}
    

    Note: the received action is now on the comments controller

    0 讨论(0)
提交回复
热议问题