has_many through additional attributes

后端 未结 4 714
温柔的废话
温柔的废话 2020-12-15 08:48

How do we set additional parameters in has_many through associations?

Thanks. Neelesh

相关标签:
4条回答
  • 2020-12-15 08:49

    Got the same problem here. Can't find any tutorials how to make it work on-the-fly in Rails 3. But you can still get what you want through the join model itself.

    p = Post.new(:title => 'Post', :body => 'Lorem ipsum ...')
    t = Tag.new(:title => 'Tag')
    
    p.tags << t
    p.save   # saves post, tag and also add record to posttags table, but additional attribute is NULL now
    j = PostTag.find_by_post_id_and_tag_id(p,t)
    j.user_id = params[:user_id]
    j.save   # this finally saves additional attribute
    

    Pretty ugly but this works from me.

    0 讨论(0)
  • 2020-12-15 08:56

    Well I was in a similar situation where I wanted to have a join table that joined 3 models. But I wanted the third model ID to be gotten from the second model.

    class Ingredient < ActiveRecord::Base
    
    end
    
    class Person < ActiveRecord::Base
      has_many :food
      has_many :ingredients_food_person
      has_many :ingredients, through: :ingredients_food_person
    end
    
    class Food
      belongs_to :person
      has_many :ingredient_food_person
      has_many :ingredients, through: :ingredients_food_person
    
      before_save do
        ingredients_food_person.each { |ifp| ifp.person_id = person_id }
      end
    end
    
    class IngredientFoodPerson < ActiveRecord::Base
      belongs_to :ingredient
      belongs_to :food
      belongs_to :person
    end
    

    And surprisingly, you can do something like this:

    food = Food.new ingredients: [Ingredient.new, Ingredient.new]
    food.ingredients_food_person.size # => 2
    food.save
    

    At first I thought that before I saved, I wouldn't have access to #ingredients_food_person after assigning #ingredients. But it generates the models automatically.

    0 讨论(0)
  • 2020-12-15 08:59
    has_many :tags, :through => :post_tags, :conditions => ['tag.owner_id = ?' @owner.id]
    
    0 讨论(0)
  • 2020-12-15 09:01

    This blog post has the perfect solution: http://www.tweetegy.com/2011/02/setting-join-table-attribute-has_many-through-association-in-rails-activerecord/

    That solution is: create your ":through model" manually, rather than through the automated way when you append to its owner's array.

    Using the example from that blog post. Where your models are:

    class Product < ActiveRecord::Base
      has_many :collaborators
      has_many :users, :through => :collaborators
    end
    
    class User < ActiveRecord::Base
      has_many :collaborators
      has_many :products, :through => :collaborators
    end
    
    class Collaborator < ActiveRecord::Base
      belongs_to :product
      belongs_to :user
    end
    

    Previously you may have gone: product.collaborators << current_user.

    However, to set the additional argument (in this example is_admin), rather than the automated way of appending to the array, you can do it manually like:

    product.save && product.collaborators.create(:user => current_user, :is_admin => true)

    This approach allows you to set the additional arguments at save-time. NB. the product.save is necessary if the model hasn't yet been saved, otherwise it can be omitted.

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