0

My application consists of these five models: A supermarket can have different categories of products and the products in these categories can be produced by several brands.

Now I want to have one (or two) Selection-field(s) in my supermarket-form in which I can select one element in Category with its name appearing and one or more element(s) in Brand with its name appearing, so this could be stored in Origin.

I think I could use collection_select, but how do I utilize it here?

class Supermarket < ActiveRecord::Base
  has_many :supplies
  has_many :origins, :through => :supplies
end

class Supply < ActiveRecord::Base  
  belongs_to :origin  
  belongs_to :supermarket  
end

class Origin < ActiveRecord::Base
  belongs_to :category
  belongs_to :brand
end

class Category < ActiveRecord::Base
  has_many :origins
end

class Brand < ActiveRecord::Base
  has_many :origins
end

Probably, I also have to tweak the models...


Edit

To clarify what the outcome of the form should be:

In the form to edit Supermarkets I want to select a Category of products and the corresponding Brands so that I know, which Category and which Brands in this Category is/are sold in this specific Supermarket:

Supermarket (Form):

Name of Supermarket: Walmart


Category (Select one):

  • Cola (Category_ID 1)
  • Cornflakes (Category_ID 2)
  • ...

Brand (multiple Select)

  • The Coca-Cola Company (Brand_ID 1)
  • PepsiCo (Brand_ID 2)
  • Kellogg Company (Brand_ID 3)
  • ...

This should create entries in Origin like:

Supermarket_ID Category_ID Brand_ID 
      1            1          1 
      1            1          2 
      2            1          2 
      2            2          3 
     ...          ...        ... 

/Edit


Edit 2

According to the answer to this question, I could create or select an entry via console like this:

walmart = Supermarket.create(:name => "Walmart");
cornflakes = Category.create(:name => "Corn Flakes");
kellogs = Brand.create(:name => "Kellog's");

walmart.origins.create(:category_id => cornflakes, :brand_id = kellogs)

How can I make use of this via a form? How could I utilize select or collection_select or is there even another helper I could use?

/Edit 2

Community
  • 1
  • 1
c_ern
  • 151
  • 2
  • 11

1 Answers1

0

I have also had a similar problem when utilizing many-to-many relationships. One worthwhile gem to check out would be simple_form.

They have a nice form helper for to_many associations.

In terms of actually implementing the form, I'm not sure I understood how the form data will be used. Regardless, javascript and virtual attributes are your friends here.

EDIT:

Ah, I see what you're saying. the way I would do this would be to create one select_field, for selecting the category, then I would create another select_field (setting :multiple => true) so I can select multiple brands.

<%= select_tag "supermarket[supplies][][category]" ... %>
<%= select_tag "supermarket[supplies][][brands]", ... %> <!-- be sure to set multiple to true !-->

Next, you need to associate everything together. So for that, I would create a virtual attribute that handles the form submission. For example:

def supplies=(supplies_hash)
# read supplies_hash and create the active records. 
end

def supplies

end

Finally, if you're insisting on doing this without a gem, I recommend you take a look at the nested form railscast. to get an idea of what's involved.

Eytan
  • 1,825
  • 17
  • 24
  • I see, but there must be a way without additional gems... Should be a common problem. Furthermore my goal is to understand how to work with relationships and entering data in the correct table... – c_ern Sep 20 '12 at 08:59
  • You're absolutely right. It's worthwhile to learn what's involved in implementing this without gems. However, once you do it once, you'll likely want to use the gems to save time. What you are doing in this form is nesting a number of active record models. You'll have a much easier time if you spread this functionality to a separate form after you create the supermarket. Doing so would allow you not to nest any models and have an easier time. – Eytan Sep 20 '12 at 20:53
  • You mean I should create a form where I would have 3 select fields? For `Supermarket`, `Category` and `Brand`? I have watched the Nested Forms-Railscast several times before, but I did not figure out how to apply it to this situation where there is a has_many "chaining". – c_ern Sep 21 '12 at 07:08
  • Furthermore I don't understand what a select field's return value is & how I would work with it in the controller. Without a form I could create a new entry in origins like `walmart = Supermarket.create(:name => "Walmart");` `cornflakes = Category.create(:name => "Corn Flakes");` `kellogs = Brand.create(:name => "Kellog's");` `walmart.origins.create(:category_id => cornflakes, :brand_id = kellogs)` like in the answer to [this question](http://stackoverflow.com/questions/12445675/many-to-many-to-many-relationship-with-need-for-another-specific-model) (thanks @marlin-pierce). – c_ern Sep 21 '12 at 07:12