Reputation: 3383
I have three relevant models:
class InventoryItem < ActiveRecord::Base
belongs_to :item, :foreign_key => :item_id
belongs_to :vendor
has_many :shopping_list_items
class ShoppingList < ActiveRecord::Base
has_many :shopping_list_items
belongs_to :user
end
class ShoppingListItem < ActiveRecord::Base
belongs_to :shopping_list
belongs_to :inventory_item
end
What I am trying to do is create a sidebar shopping list that will autoupdate ShoppingListItem attributes (specifically price) when a respective attribute is changed in the InventoryItem table (again, price). My thinking was to have these three classes and map ShoppingListItems directly to InventoryItems, but I'm unsure of how to proceed with that. Alternatively, is it possible to do away with the ShoppingListItem class entirely and make ShoppingList be a collection of InventoryItems specified by the user? Any input is much appreciated. Thanks in advance!
Upvotes: 0
Views: 184
Reputation: 2232
To redo my comments as a real answer, yes, it is possible to forego the ShoppingListItem
model in this case, as long as you don't need to attach any data to that model itself (e.g. the time the item was added to the list). You could link your models as follows with a has_and_belongs_to_many
association:
class InventoryItem < ActiveRecord::Base
belongs_to :item
belongs_to :vendor
has_and_belongs_to_many :shopping_lists
end
class ShoppingList < ActiveRecord::Base
belongs_to :user
has_and_belongs_to_many :inventory_items
end
This will allow you to assign an array of inventory items to the inventory_items
attribute of a shopping list, and Rails will create or delete the necessary join records automatically. More information from the Rails guides. Note that you'll still need a join table in your schema -- there just isn't a model associated with it. In your case, the migration might look like this:
create_table :inventory_items_shopping_lists, id: false do |t|
t.references :inventory_item
t.references :shopping_list
end
add_index :inventory_items_shopping_lists, :inventory_item_id
add_index :inventory_items_shopping_lists, :shopping_list_id
add_index :inventory_items_shopping_lists, [:inventory_item_id, :shopping_list_id], unique: true
Note that in order for Rails to auto-detect the table, its name should be the combined plural forms of both models in alphabetical order. Otherwise you need to specify the table name using the join_table
option when defining the association.
Upvotes: 1