Creating a many to many relationship in Rails












57















This is a simplified example of what I am trying to achieve, I'm relatively new to Rails and am struggling to get my head around relationships between models.



I have two models, the User model and the Category model. A user can be associated with many categories. A particular category can appear in the category list for many users. If a particular category is deleted, this should be reflected in the category list for a user.



In this example:



My Categories table contains five categories:




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ID | Name |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 1 | Sports |
| 2 | News |
| 3 | Entertainment |
| 4 | Technology |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


My Users table contains two users:




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ID | Name |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 1 | UserA |
| 2 | UserB |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



UserA may choose Sports and Technology as his categories



UserB may choose News, Sports and Entertainment



The sports category is deleted, both UserA and UserB category lists reflect the deletion




I've toyed around with creating a UserCategories table which holds the ids of both a category and user. This kind of worked, I could look up the category names but I couldn't get a cascading delete to work and the whole solution just seemed wrong.



The examples of using the belongs_to and has_many functions that I have found seem to discuss mapping a one-to-one relationship. For example, comments on a blog post.




  • How do you represent this many-to-many relationship using the built-in Rails functionality?

  • Is using a separate table between the two a viable solution when using Rails?










share|improve this question

























  • Actually, there's nothing wrong with using UserCategory model, it's even desirable in most cases. You just need to use User.has_many :categories, through: :user_categories. Maybe, a better name could be found though.

    – RocketR
    Jul 20 '12 at 13:25











  • For others, there is a good rails cast here about the subject: railscasts.com/episodes/47-two-many-to-many

    – Dofs
    Jan 26 '13 at 14:31
















57















This is a simplified example of what I am trying to achieve, I'm relatively new to Rails and am struggling to get my head around relationships between models.



I have two models, the User model and the Category model. A user can be associated with many categories. A particular category can appear in the category list for many users. If a particular category is deleted, this should be reflected in the category list for a user.



In this example:



My Categories table contains five categories:




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ID | Name |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 1 | Sports |
| 2 | News |
| 3 | Entertainment |
| 4 | Technology |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


My Users table contains two users:




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ID | Name |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 1 | UserA |
| 2 | UserB |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



UserA may choose Sports and Technology as his categories



UserB may choose News, Sports and Entertainment



The sports category is deleted, both UserA and UserB category lists reflect the deletion




I've toyed around with creating a UserCategories table which holds the ids of both a category and user. This kind of worked, I could look up the category names but I couldn't get a cascading delete to work and the whole solution just seemed wrong.



The examples of using the belongs_to and has_many functions that I have found seem to discuss mapping a one-to-one relationship. For example, comments on a blog post.




  • How do you represent this many-to-many relationship using the built-in Rails functionality?

  • Is using a separate table between the two a viable solution when using Rails?










share|improve this question

























  • Actually, there's nothing wrong with using UserCategory model, it's even desirable in most cases. You just need to use User.has_many :categories, through: :user_categories. Maybe, a better name could be found though.

    – RocketR
    Jul 20 '12 at 13:25











  • For others, there is a good rails cast here about the subject: railscasts.com/episodes/47-two-many-to-many

    – Dofs
    Jan 26 '13 at 14:31














57












57








57


29






This is a simplified example of what I am trying to achieve, I'm relatively new to Rails and am struggling to get my head around relationships between models.



I have two models, the User model and the Category model. A user can be associated with many categories. A particular category can appear in the category list for many users. If a particular category is deleted, this should be reflected in the category list for a user.



In this example:



My Categories table contains five categories:




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ID | Name |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 1 | Sports |
| 2 | News |
| 3 | Entertainment |
| 4 | Technology |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


My Users table contains two users:




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ID | Name |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 1 | UserA |
| 2 | UserB |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



UserA may choose Sports and Technology as his categories



UserB may choose News, Sports and Entertainment



The sports category is deleted, both UserA and UserB category lists reflect the deletion




I've toyed around with creating a UserCategories table which holds the ids of both a category and user. This kind of worked, I could look up the category names but I couldn't get a cascading delete to work and the whole solution just seemed wrong.



The examples of using the belongs_to and has_many functions that I have found seem to discuss mapping a one-to-one relationship. For example, comments on a blog post.




  • How do you represent this many-to-many relationship using the built-in Rails functionality?

  • Is using a separate table between the two a viable solution when using Rails?










share|improve this question
















This is a simplified example of what I am trying to achieve, I'm relatively new to Rails and am struggling to get my head around relationships between models.



I have two models, the User model and the Category model. A user can be associated with many categories. A particular category can appear in the category list for many users. If a particular category is deleted, this should be reflected in the category list for a user.



In this example:



My Categories table contains five categories:




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ID | Name |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 1 | Sports |
| 2 | News |
| 3 | Entertainment |
| 4 | Technology |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


My Users table contains two users:




~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ID | Name |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 1 | UserA |
| 2 | UserB |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



UserA may choose Sports and Technology as his categories



UserB may choose News, Sports and Entertainment



The sports category is deleted, both UserA and UserB category lists reflect the deletion




I've toyed around with creating a UserCategories table which holds the ids of both a category and user. This kind of worked, I could look up the category names but I couldn't get a cascading delete to work and the whole solution just seemed wrong.



The examples of using the belongs_to and has_many functions that I have found seem to discuss mapping a one-to-one relationship. For example, comments on a blog post.




  • How do you represent this many-to-many relationship using the built-in Rails functionality?

  • Is using a separate table between the two a viable solution when using Rails?







ruby-on-rails






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jul 18 '17 at 22:14









coreyward

50k1596124




50k1596124










asked Feb 25 '11 at 17:46









fletcherfletcher

9,24864465




9,24864465













  • Actually, there's nothing wrong with using UserCategory model, it's even desirable in most cases. You just need to use User.has_many :categories, through: :user_categories. Maybe, a better name could be found though.

    – RocketR
    Jul 20 '12 at 13:25











  • For others, there is a good rails cast here about the subject: railscasts.com/episodes/47-two-many-to-many

    – Dofs
    Jan 26 '13 at 14:31



















  • Actually, there's nothing wrong with using UserCategory model, it's even desirable in most cases. You just need to use User.has_many :categories, through: :user_categories. Maybe, a better name could be found though.

    – RocketR
    Jul 20 '12 at 13:25











  • For others, there is a good rails cast here about the subject: railscasts.com/episodes/47-two-many-to-many

    – Dofs
    Jan 26 '13 at 14:31

















Actually, there's nothing wrong with using UserCategory model, it's even desirable in most cases. You just need to use User.has_many :categories, through: :user_categories. Maybe, a better name could be found though.

– RocketR
Jul 20 '12 at 13:25





Actually, there's nothing wrong with using UserCategory model, it's even desirable in most cases. You just need to use User.has_many :categories, through: :user_categories. Maybe, a better name could be found though.

– RocketR
Jul 20 '12 at 13:25













For others, there is a good rails cast here about the subject: railscasts.com/episodes/47-two-many-to-many

– Dofs
Jan 26 '13 at 14:31





For others, there is a good rails cast here about the subject: railscasts.com/episodes/47-two-many-to-many

– Dofs
Jan 26 '13 at 14:31












2 Answers
2






active

oldest

votes


















129














You want a has_and_belongs_to_many relationship. The guide does a great job of describing how this works with charts and everything:



http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association



You will end up with something like this:



# app/models/category.rb
class Category < ActiveRecord::Base
has_and_belongs_to_many :users
end

# app/models/user.rb
class User < ActiveRecord::Base
has_and_belongs_to_many :categories
end


Now you need to create a join table for Rails to use. Rails will not do this automatically for you. This is effectively a table with a reference to each of Categories and Users, and no primary key.



Generate a migration from the CLI like this:



bin/rails g migration CreateCategoriesUsersJoinTable


Then open it up and edit it to match:



For Rails 4.0.2+ (including Rails 5.2):



def change
# This is enough; you don't need to worry about order
create_join_table :categories, :users

# If you want to add an index for faster querying through this join:
create_join_table :categories, :users do |t|
t.index :category_id
t.index :user_id
end
end


Rails < 4.0.2:



def self.up
# Model names in alphabetical order (e.g. a_b)
create_table :categories_users, :id => false do |t|
t.integer :category_id
t.integer :user_id
end

add_index :categories_users, [:category_id, :user_id]
end

def self.down
drop_table :categories_users
end


With that in place, run your migrations and you can connect Categories and Users with all of the convenient accessors you're used to:



User.categories  #=> [<Category @name="Sports">, ...]
Category.users #=> [<User @name="UserA">, ...]
User.categories.empty?





share|improve this answer





















  • 9





    One additional tip: create a composite index for the table. More here stackoverflow.com/a/4381282/14540

    – kolrie
    Feb 26 '13 at 21:47






  • 1





    @kolrie Great point; I added to the example here for the sake of being thorough. Cheers!

    – coreyward
    Feb 27 '13 at 5:04






  • 4





    dumb question, does this mean it's necessary to create a new model?

    – tvieira
    Jan 9 '14 at 20:20











  • has_and_belongs_to_many does not need/create model. If you need to work directly with the relation or need to add attributes to the relationship, you should use has_many :through option. Follow the link in the answer for detailed info.

    – Chong Yu
    Sep 29 '14 at 19:53






  • 12





    Another thing I noticed is the naming convention of the joining table. It has to be alphabetically ordered. Using the above example, the table name has to be categories_users and not users_categories. "c" before "u" in this case.

    – Chong Yu
    Sep 29 '14 at 19:55



















0














Just complementing coreyward's answer above:
If you already have a model that has a belongs_to, has_many relation and you want to create a new relation has_and_belongs_to_many using the same table you will need to:



rails g migration CreateJoinTableUsersCategories users categories


Then,



rake db:migrate


After that, you will need to define your relations:



User.rb:



class Region < ApplicationRecord
has_and_belongs_to_many :categories
end


Category.rb



class Facility < ApplicationRecord
has_and_belongs_to_many :users
end


In order to populate the new join table with the old data, you will need to in your console:



User.all.find_each do |u|
Category.where(user_id: u.id).find_each do |c|
u.categories << c
end
end


You can either leave the user_id column and category_id column from the Category and User tables or create a migration to delete it.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5120703%2fcreating-a-many-to-many-relationship-in-rails%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    129














    You want a has_and_belongs_to_many relationship. The guide does a great job of describing how this works with charts and everything:



    http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association



    You will end up with something like this:



    # app/models/category.rb
    class Category < ActiveRecord::Base
    has_and_belongs_to_many :users
    end

    # app/models/user.rb
    class User < ActiveRecord::Base
    has_and_belongs_to_many :categories
    end


    Now you need to create a join table for Rails to use. Rails will not do this automatically for you. This is effectively a table with a reference to each of Categories and Users, and no primary key.



    Generate a migration from the CLI like this:



    bin/rails g migration CreateCategoriesUsersJoinTable


    Then open it up and edit it to match:



    For Rails 4.0.2+ (including Rails 5.2):



    def change
    # This is enough; you don't need to worry about order
    create_join_table :categories, :users

    # If you want to add an index for faster querying through this join:
    create_join_table :categories, :users do |t|
    t.index :category_id
    t.index :user_id
    end
    end


    Rails < 4.0.2:



    def self.up
    # Model names in alphabetical order (e.g. a_b)
    create_table :categories_users, :id => false do |t|
    t.integer :category_id
    t.integer :user_id
    end

    add_index :categories_users, [:category_id, :user_id]
    end

    def self.down
    drop_table :categories_users
    end


    With that in place, run your migrations and you can connect Categories and Users with all of the convenient accessors you're used to:



    User.categories  #=> [<Category @name="Sports">, ...]
    Category.users #=> [<User @name="UserA">, ...]
    User.categories.empty?





    share|improve this answer





















    • 9





      One additional tip: create a composite index for the table. More here stackoverflow.com/a/4381282/14540

      – kolrie
      Feb 26 '13 at 21:47






    • 1





      @kolrie Great point; I added to the example here for the sake of being thorough. Cheers!

      – coreyward
      Feb 27 '13 at 5:04






    • 4





      dumb question, does this mean it's necessary to create a new model?

      – tvieira
      Jan 9 '14 at 20:20











    • has_and_belongs_to_many does not need/create model. If you need to work directly with the relation or need to add attributes to the relationship, you should use has_many :through option. Follow the link in the answer for detailed info.

      – Chong Yu
      Sep 29 '14 at 19:53






    • 12





      Another thing I noticed is the naming convention of the joining table. It has to be alphabetically ordered. Using the above example, the table name has to be categories_users and not users_categories. "c" before "u" in this case.

      – Chong Yu
      Sep 29 '14 at 19:55
















    129














    You want a has_and_belongs_to_many relationship. The guide does a great job of describing how this works with charts and everything:



    http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association



    You will end up with something like this:



    # app/models/category.rb
    class Category < ActiveRecord::Base
    has_and_belongs_to_many :users
    end

    # app/models/user.rb
    class User < ActiveRecord::Base
    has_and_belongs_to_many :categories
    end


    Now you need to create a join table for Rails to use. Rails will not do this automatically for you. This is effectively a table with a reference to each of Categories and Users, and no primary key.



    Generate a migration from the CLI like this:



    bin/rails g migration CreateCategoriesUsersJoinTable


    Then open it up and edit it to match:



    For Rails 4.0.2+ (including Rails 5.2):



    def change
    # This is enough; you don't need to worry about order
    create_join_table :categories, :users

    # If you want to add an index for faster querying through this join:
    create_join_table :categories, :users do |t|
    t.index :category_id
    t.index :user_id
    end
    end


    Rails < 4.0.2:



    def self.up
    # Model names in alphabetical order (e.g. a_b)
    create_table :categories_users, :id => false do |t|
    t.integer :category_id
    t.integer :user_id
    end

    add_index :categories_users, [:category_id, :user_id]
    end

    def self.down
    drop_table :categories_users
    end


    With that in place, run your migrations and you can connect Categories and Users with all of the convenient accessors you're used to:



    User.categories  #=> [<Category @name="Sports">, ...]
    Category.users #=> [<User @name="UserA">, ...]
    User.categories.empty?





    share|improve this answer





















    • 9





      One additional tip: create a composite index for the table. More here stackoverflow.com/a/4381282/14540

      – kolrie
      Feb 26 '13 at 21:47






    • 1





      @kolrie Great point; I added to the example here for the sake of being thorough. Cheers!

      – coreyward
      Feb 27 '13 at 5:04






    • 4





      dumb question, does this mean it's necessary to create a new model?

      – tvieira
      Jan 9 '14 at 20:20











    • has_and_belongs_to_many does not need/create model. If you need to work directly with the relation or need to add attributes to the relationship, you should use has_many :through option. Follow the link in the answer for detailed info.

      – Chong Yu
      Sep 29 '14 at 19:53






    • 12





      Another thing I noticed is the naming convention of the joining table. It has to be alphabetically ordered. Using the above example, the table name has to be categories_users and not users_categories. "c" before "u" in this case.

      – Chong Yu
      Sep 29 '14 at 19:55














    129












    129








    129







    You want a has_and_belongs_to_many relationship. The guide does a great job of describing how this works with charts and everything:



    http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association



    You will end up with something like this:



    # app/models/category.rb
    class Category < ActiveRecord::Base
    has_and_belongs_to_many :users
    end

    # app/models/user.rb
    class User < ActiveRecord::Base
    has_and_belongs_to_many :categories
    end


    Now you need to create a join table for Rails to use. Rails will not do this automatically for you. This is effectively a table with a reference to each of Categories and Users, and no primary key.



    Generate a migration from the CLI like this:



    bin/rails g migration CreateCategoriesUsersJoinTable


    Then open it up and edit it to match:



    For Rails 4.0.2+ (including Rails 5.2):



    def change
    # This is enough; you don't need to worry about order
    create_join_table :categories, :users

    # If you want to add an index for faster querying through this join:
    create_join_table :categories, :users do |t|
    t.index :category_id
    t.index :user_id
    end
    end


    Rails < 4.0.2:



    def self.up
    # Model names in alphabetical order (e.g. a_b)
    create_table :categories_users, :id => false do |t|
    t.integer :category_id
    t.integer :user_id
    end

    add_index :categories_users, [:category_id, :user_id]
    end

    def self.down
    drop_table :categories_users
    end


    With that in place, run your migrations and you can connect Categories and Users with all of the convenient accessors you're used to:



    User.categories  #=> [<Category @name="Sports">, ...]
    Category.users #=> [<User @name="UserA">, ...]
    User.categories.empty?





    share|improve this answer















    You want a has_and_belongs_to_many relationship. The guide does a great job of describing how this works with charts and everything:



    http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association



    You will end up with something like this:



    # app/models/category.rb
    class Category < ActiveRecord::Base
    has_and_belongs_to_many :users
    end

    # app/models/user.rb
    class User < ActiveRecord::Base
    has_and_belongs_to_many :categories
    end


    Now you need to create a join table for Rails to use. Rails will not do this automatically for you. This is effectively a table with a reference to each of Categories and Users, and no primary key.



    Generate a migration from the CLI like this:



    bin/rails g migration CreateCategoriesUsersJoinTable


    Then open it up and edit it to match:



    For Rails 4.0.2+ (including Rails 5.2):



    def change
    # This is enough; you don't need to worry about order
    create_join_table :categories, :users

    # If you want to add an index for faster querying through this join:
    create_join_table :categories, :users do |t|
    t.index :category_id
    t.index :user_id
    end
    end


    Rails < 4.0.2:



    def self.up
    # Model names in alphabetical order (e.g. a_b)
    create_table :categories_users, :id => false do |t|
    t.integer :category_id
    t.integer :user_id
    end

    add_index :categories_users, [:category_id, :user_id]
    end

    def self.down
    drop_table :categories_users
    end


    With that in place, run your migrations and you can connect Categories and Users with all of the convenient accessors you're used to:



    User.categories  #=> [<Category @name="Sports">, ...]
    Category.users #=> [<User @name="UserA">, ...]
    User.categories.empty?






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 19 '18 at 16:30

























    answered Feb 25 '11 at 17:48









    coreywardcoreyward

    50k1596124




    50k1596124








    • 9





      One additional tip: create a composite index for the table. More here stackoverflow.com/a/4381282/14540

      – kolrie
      Feb 26 '13 at 21:47






    • 1





      @kolrie Great point; I added to the example here for the sake of being thorough. Cheers!

      – coreyward
      Feb 27 '13 at 5:04






    • 4





      dumb question, does this mean it's necessary to create a new model?

      – tvieira
      Jan 9 '14 at 20:20











    • has_and_belongs_to_many does not need/create model. If you need to work directly with the relation or need to add attributes to the relationship, you should use has_many :through option. Follow the link in the answer for detailed info.

      – Chong Yu
      Sep 29 '14 at 19:53






    • 12





      Another thing I noticed is the naming convention of the joining table. It has to be alphabetically ordered. Using the above example, the table name has to be categories_users and not users_categories. "c" before "u" in this case.

      – Chong Yu
      Sep 29 '14 at 19:55














    • 9





      One additional tip: create a composite index for the table. More here stackoverflow.com/a/4381282/14540

      – kolrie
      Feb 26 '13 at 21:47






    • 1





      @kolrie Great point; I added to the example here for the sake of being thorough. Cheers!

      – coreyward
      Feb 27 '13 at 5:04






    • 4





      dumb question, does this mean it's necessary to create a new model?

      – tvieira
      Jan 9 '14 at 20:20











    • has_and_belongs_to_many does not need/create model. If you need to work directly with the relation or need to add attributes to the relationship, you should use has_many :through option. Follow the link in the answer for detailed info.

      – Chong Yu
      Sep 29 '14 at 19:53






    • 12





      Another thing I noticed is the naming convention of the joining table. It has to be alphabetically ordered. Using the above example, the table name has to be categories_users and not users_categories. "c" before "u" in this case.

      – Chong Yu
      Sep 29 '14 at 19:55








    9




    9





    One additional tip: create a composite index for the table. More here stackoverflow.com/a/4381282/14540

    – kolrie
    Feb 26 '13 at 21:47





    One additional tip: create a composite index for the table. More here stackoverflow.com/a/4381282/14540

    – kolrie
    Feb 26 '13 at 21:47




    1




    1





    @kolrie Great point; I added to the example here for the sake of being thorough. Cheers!

    – coreyward
    Feb 27 '13 at 5:04





    @kolrie Great point; I added to the example here for the sake of being thorough. Cheers!

    – coreyward
    Feb 27 '13 at 5:04




    4




    4





    dumb question, does this mean it's necessary to create a new model?

    – tvieira
    Jan 9 '14 at 20:20





    dumb question, does this mean it's necessary to create a new model?

    – tvieira
    Jan 9 '14 at 20:20













    has_and_belongs_to_many does not need/create model. If you need to work directly with the relation or need to add attributes to the relationship, you should use has_many :through option. Follow the link in the answer for detailed info.

    – Chong Yu
    Sep 29 '14 at 19:53





    has_and_belongs_to_many does not need/create model. If you need to work directly with the relation or need to add attributes to the relationship, you should use has_many :through option. Follow the link in the answer for detailed info.

    – Chong Yu
    Sep 29 '14 at 19:53




    12




    12





    Another thing I noticed is the naming convention of the joining table. It has to be alphabetically ordered. Using the above example, the table name has to be categories_users and not users_categories. "c" before "u" in this case.

    – Chong Yu
    Sep 29 '14 at 19:55





    Another thing I noticed is the naming convention of the joining table. It has to be alphabetically ordered. Using the above example, the table name has to be categories_users and not users_categories. "c" before "u" in this case.

    – Chong Yu
    Sep 29 '14 at 19:55













    0














    Just complementing coreyward's answer above:
    If you already have a model that has a belongs_to, has_many relation and you want to create a new relation has_and_belongs_to_many using the same table you will need to:



    rails g migration CreateJoinTableUsersCategories users categories


    Then,



    rake db:migrate


    After that, you will need to define your relations:



    User.rb:



    class Region < ApplicationRecord
    has_and_belongs_to_many :categories
    end


    Category.rb



    class Facility < ApplicationRecord
    has_and_belongs_to_many :users
    end


    In order to populate the new join table with the old data, you will need to in your console:



    User.all.find_each do |u|
    Category.where(user_id: u.id).find_each do |c|
    u.categories << c
    end
    end


    You can either leave the user_id column and category_id column from the Category and User tables or create a migration to delete it.






    share|improve this answer




























      0














      Just complementing coreyward's answer above:
      If you already have a model that has a belongs_to, has_many relation and you want to create a new relation has_and_belongs_to_many using the same table you will need to:



      rails g migration CreateJoinTableUsersCategories users categories


      Then,



      rake db:migrate


      After that, you will need to define your relations:



      User.rb:



      class Region < ApplicationRecord
      has_and_belongs_to_many :categories
      end


      Category.rb



      class Facility < ApplicationRecord
      has_and_belongs_to_many :users
      end


      In order to populate the new join table with the old data, you will need to in your console:



      User.all.find_each do |u|
      Category.where(user_id: u.id).find_each do |c|
      u.categories << c
      end
      end


      You can either leave the user_id column and category_id column from the Category and User tables or create a migration to delete it.






      share|improve this answer


























        0












        0








        0







        Just complementing coreyward's answer above:
        If you already have a model that has a belongs_to, has_many relation and you want to create a new relation has_and_belongs_to_many using the same table you will need to:



        rails g migration CreateJoinTableUsersCategories users categories


        Then,



        rake db:migrate


        After that, you will need to define your relations:



        User.rb:



        class Region < ApplicationRecord
        has_and_belongs_to_many :categories
        end


        Category.rb



        class Facility < ApplicationRecord
        has_and_belongs_to_many :users
        end


        In order to populate the new join table with the old data, you will need to in your console:



        User.all.find_each do |u|
        Category.where(user_id: u.id).find_each do |c|
        u.categories << c
        end
        end


        You can either leave the user_id column and category_id column from the Category and User tables or create a migration to delete it.






        share|improve this answer













        Just complementing coreyward's answer above:
        If you already have a model that has a belongs_to, has_many relation and you want to create a new relation has_and_belongs_to_many using the same table you will need to:



        rails g migration CreateJoinTableUsersCategories users categories


        Then,



        rake db:migrate


        After that, you will need to define your relations:



        User.rb:



        class Region < ApplicationRecord
        has_and_belongs_to_many :categories
        end


        Category.rb



        class Facility < ApplicationRecord
        has_and_belongs_to_many :users
        end


        In order to populate the new join table with the old data, you will need to in your console:



        User.all.find_each do |u|
        Category.where(user_id: u.id).find_each do |c|
        u.categories << c
        end
        end


        You can either leave the user_id column and category_id column from the Category and User tables or create a migration to delete it.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 21 at 22:10









        Bruno MBruno M

        214




        214






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f5120703%2fcreating-a-many-to-many-relationship-in-rails%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)