Search code examples
ruby-on-railsrubymodels

Data Modeling Structure - Rails


I have a project-specific question. I'm trying to determine the most efficient and logical way of setting up my models in my app. The relevant players to model here are: Vendors, Vendor Inventories, and Products. Here is a breakdown of what each item should be able to return in some way:

Inventories: Store ID Products and associated details (Price, Name, Brand, Details, Product Code)

Vendors: Store ID, Location, Name

Products: Price, Name, Brand, Details, Product Code

Obviously there is a lot of duplication in this scheme between products and inventories. My issue is that while vendors might have similar items in their inventories, the price will always be different. So I can't simply relate the models by product code. Because most vendors will have the same products, if I were to model store inventories with all of the product information, wouldn't that be a lot of duplication? It's also possible that I don't need to have a separate model for vendors and could just try and keep it all inventories, but I'm lost. Help please?! Thanks in advance.

EDIT:

Here is my model structure, though I'm not sure it's ideal.

class Vendor < ActiveRecord::Base

    attr_accessible :name, :address

    has_one     :inventory
    has_many    :products, through: :inventories
end

class Inventory < ActiveRecord::Base

    has_many    :products
    belongs_to  :vendor
end

class Product < ActiveRecord::Base

    attr_accessible :upc, :brand, :product, :details, :price

    has_many    :inventories
    has_many    :vendors, through: :inventories

end

Solution

  • I'm not sure if I understand your specific needs, especially if the set of models are just for example, but judging from the names, here would be my implementation.

    A Vendor is the main entity, it will own many products through the join table inventory,

    class Vendor < ActiveRecord::Base
    
        attr_accessible :name, :address
    
        has_many     :inventories
        has_many    :products, through: :inventories
    end
    

    However there are aspects of the product that need to differ between Vendors, in this case, price and quantity( I just made that up), which can be stored in the join table, since it would be independent and made for each product and vendor relationship, is ideal for storing info like price and quantity.

    class Inventory < ActiveRecord::Base
    
        attr_accessible :product_id, :vendor_id, :price, :quantity
    
        belongs_to  :product
        belongs_to  :vendor
    end
    

    Product should only have attributes that would be universal regardless how the vendor handles it, likewise if the product where to be changed, it should be okay with all the vendors.

    class Product < ActiveRecord::Base
    
        attr_accessible :upc, :brand, :product, :details
    
        has_many    :inventories
        has_many    :vendors, through: :inventories
    
    end
    

    Doing this you may have difficulties editing this in the view, setting prices and quantity on inventory. Again, my way of doing it would be to use nested fields and interact directly with the join table, and not products, here's some quick partial code using simple_form gem,

    on you form,

      <%= f.simple_fields_for :inventories do |inventory_fields| %>
          <%= render partial: "inventory_fields", locals: {f: inventory_fields }%>
      <% end %>
      <%= link_to_add_fields "Add", f, :f %>
    

    and in inventory_fields.html.erb

      <%= link_to "Remove", '#', class: "remove_fields btn btn-danger" %>
      <%= f.input :product_id, collection: Product.all.somethingsomething, include_blank: false %>
      <%= f.input :price %>
      <%= f.input :quantity %>
    

    Now you can choose your products from a dropdown, and set price and quantity, and whatever you need dynamically.