using has_many :through and build

后端 未结 3 983
半阙折子戏
半阙折子戏 2020-12-05 12:15

i have three models, all for a has_many :through relationship. They look like this:

class Company < ActiveRecord::Base

  has_many :company_users, depende         


        
相关标签:
3条回答
  • 2020-12-05 12:43

    If you have a has_many :through association and you want to save an association using build you can accomplish this using the :inverse_of option on the belongs_to association in the Join Model

    Here's a modified example from the rails docs where tags has a has_many :through association with posts and the developer is attempting to save tags through the join model (PostTag) using the build method:

    @post = Post.first
    @tag = @post.tags.build name: "ruby"
    @tag.save
    
    

    The common expectation is that the last line should save the "through" record in the join table (post_tags). However, this will not work by default. This will only work if the :inverse_of is set:

    class PostTag < ActiveRecord::Base
      belongs_to :post
      belongs_to :tag, inverse_of: :post_tags # add inverse_of option
    end
    
    class Post < ActiveRecord::Base
      has_many :post_tags
      has_many :tags, through: :post_tags 
    end
    
    class Tag < ActiveRecord::Base
      has_many :post_tags
      has_many :posts, through: :post_tags  
    end
    
    

    So for the question above, setting the :inverse_of option on the belongs_to :user association in the Join Model (CompanyUser) like this:

    class CompanyUser < ActiveRecord::Base
      belongs_to :company
      belongs_to :user, inverse_of: :company_users
    end
    
    

    will result in the following code correctly creating a record in the join table (company_users)

    company = Company.first
    company.users.build(name: "James")
    company.save
    

    Source: here & here

    0 讨论(0)
  • 2020-12-05 12:51

    I suspect your params[:user] parameter, otherwise your code seems clean. We can use build method with 1..n and n..n associations too, see here.

    I suggest you to first make sure that your model associations works fine, for that open the console and try the following,

    > company = Company.last
    => #<Tcompany id: 1....>
    > company.users
    => []
    > company.users.build(:name => "Jake")
    => > #<User id: nil, name: "Jake">
    > company.save
    => true
    

    Now if the records are being saved fine, debug the parameters you pass to build method.

    Happy debugging :)

    0 讨论(0)
  • 2020-12-05 12:53

    You can't use a has_many :through like that, you have to do it like this:

    @company = Company.last
    @user    = User.create( params[:user] ) 
    @company.company_users.create( :user_id => @user.id )
    

    Then you will have the association defined correctly.

    update

    In the case of the comment below, as you already have accepts_nested_attributes_for, your parameters would have to come like this:

    { :company => 
        { :company_users_attributes => 
            [ 
              { :company_id => 1, :user_id => 1 } ,
              { :company_id => 1, :user_id => 2 },
              { :company_id => 1, :user_id => 3 } 
            ]
        } 
    }
    

    And you would have users being added to companies automatically for you.

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