5

I have two models User and Category.

    class User < ActiveRecord::Base
        has_and_belongs_to_many :categories
        accepts_nested_attributes_for :categories
    end

similarly

    class Category < ActiveRecord::Base
        has_and_belongs_to_many :users
    end

i have a requirement where i have to add the categories to the categories table and add the reference so that i can get the categories related to user but if another user enters the same category then i have to make use of the id instead of creating new one. How can i do it?

And one more thing is i have to add an attribute type which refers that category type. for example

user1 ----> category1, category2
user2 ----> category2

here user1 and user2 has category2 but the type in category2 may differ.So how can i maintain this? please help me. I am ready to answer your question.

logesh
  • 2,572
  • 4
  • 33
  • 60
  • Category `has_and_belongs_to_many :users` not `categories`, right? Also, what you want to do with this `type`. I don't get it.... – gabrielhilal Sep 02 '13 at 14:33
  • Thanks. I have changed and i need to have type field which says the user has category2 with type "type1" and user2 has same category2 with type "type2". where should i keep the type field. If i have type field in join table how can i add the entry and get that information? – logesh Sep 02 '13 at 14:38

1 Answers1

10

You must use has_many :through instead of HABTM to add the field type to the relationship:

class User < ActiveRecord::Base
  has_many :lines
  accepts_nested_attributes_for :lines
  has_many :categories, through: :lines
end

class Line < ActiveRecord::Base
  belongs_to :users
  belongs_to :category
end

class Category < ActiveRecord::Base
  has_many :lines
  has_many :users, through: :lines
end

Add the type attribute to the class Line.

ref: http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

You will need two controllers with the restful actions: users and categories

Then, in your user form, something like:

<%= nested_form_for @user do |f| %>
...#user attributes
<%= f.fields_for :lines do |line| %>
<%= line.label :category %>
<%= line.collection_select(:category_id, Category.all, :id, :name , {include_blank: 'Select Category'} ) %>
<%= line.label :type %>
<%= line.text_field :type %>
...#the form continues

EDIT -

The category is independent of user, as well as user is independent of category.

The association class Line will join users and categories through the category_id and user_id:

________          _______________
| user |          |     line    |          ____________
|----- |          |-------------|          | category |
| id   |----------| user_id     |          |----------|
| name |1        *| category_id |----------| id       |
| email|          | type        |*        1| name     | 
|______|          |_____________|          |__________|

example:

git hub: https://github.com/gabrielhilal/nested_form

heroku: http://nestedform.herokuapp.com/

gabrielhilal
  • 10,660
  • 6
  • 54
  • 81
  • If i use accepts_nested_attributes_for :lines then how would the category information be stored in category table. It is bit unclear for me. Could you please explain more. – logesh Sep 02 '13 at 15:17
  • Also tell me if another user enters a new value to categories it should check if the category is present already and it should just add the id of the category along with type. – logesh Sep 02 '13 at 15:23
  • It took some time for me to understand. Anyway thank you and one small correction which is the join table model should have belongs_to :user and belongs_to :category. – logesh Sep 04 '13 at 04:50
  • sorry for the mistake, but the code is right in the repository I gave u: https://github.com/gabrielhilal/nested_form/blob/master/app/models/line.rb please accept the answer if it answered your question. – gabrielhilal Sep 04 '13 at 08:53