0

I have three models. Two are related through a has_and_belongs_to_many association with the appropriate join table and one with an has_many association.

class Item < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_many :colors
end

class Color < ActivRecord::Base
  belongs_to :item
end

class User < ActiveRecord::Base
  has_and_belongs_to_many :items
end

I can create new items with a color in the following way:

@item = Item.new(name: "ball")
@item.users << @user
@item.save

@item.colors.create!(name: "blue")

The item is now linked to the user referenced by @user.

But I think there has to be another way to create items for users, like the way I added the color.

@user.item.create!(name: "car")

This doesn't work because the users-array of the created item is empty and the item does now not belong to a user.

What is the problem with this approach?

1 Answers1

0

has_and_belongs_to_many should not be used. ( github )

Instead, use a has_many with the through flag: guides.rubyonrails.org...

Something like:

class Item < ActiveRecord::Base
  has_many :user_items
  has_many :users, through: :user_items # I can never think of a good name here

  has_many :colors
  has_many :item_colors, through: :colors
end

class Color < ActiveRecord::Base
  has_many :item_colors
  has_many :items, through: :item_colors
end

class User < ActiveRecord::Base
  has_many :user_items
  has_many :items, through: :user_items
end

class ItemColor < ActiveRecord::Base
  belongs_to :item
  belongs_to :color
end

class UserItem < ActiveRecord::Base
  belongs_to :user
  belongs_to :item
end

It may seem complicated, but it will solve your problems. Also, consider the situation where many items share the same color, if there isn't a join table there, it would be more difficult to categorize items by color.

Carl
  • 993
  • 8
  • 14
  • I've tried that and I will try it again, but I don't like it to have an extra model only for the association. – Andreas Pfohl Nov 13 '13 at 08:34
  • Ok, thanks. It works now. But how can I prevent the creation of items that are not assigned to a user? I put `validates :users, presence: true` in the item model, but that's not working. – Andreas Pfohl Nov 13 '13 at 08:56
  • Ok, thanks this answers solves one of my problems. I will write another questions with the other problem. – Andreas Pfohl Nov 13 '13 at 09:55
  • I believe this would help: http://stackoverflow.com/questions/950008/validate-at-least-one-in-has-and-belongs-to-many – Carl Nov 13 '13 at 16:52
  • The extra model will really free you up. What if you want a user to be able to have more than one of a specific item. A quantity count would fit right into the UserItem. – Carl Nov 13 '13 at 16:54
  • I tried that validation method, but it does not work. See here: http://stackoverflow.com/questions/19951063/has-many-through-create-validate-presence – Andreas Pfohl Nov 13 '13 at 19:26