program story

Rails에서 다 대다 관계 생성

inputbox 2020. 11. 20. 08:57
반응형

Rails에서 다 대다 관계 생성


이것은 제가 달성하고자하는 것의 단순화 된 예입니다. 저는 비교적 Rails를 처음 접했고 모델 간의 관계를 파악하는 데 어려움을 겪고 있습니다.

저는 User모델과 모델의 두 가지 모델 Category있습니다. 사용자는 여러 범주와 연관 될 수 있습니다. 특정 범주는 많은 사용자의 범주 목록에 나타날 수 있습니다. 특정 카테고리가 삭제되면 사용자의 카테고리 목록에 반영되어야합니다.

이 예에서 :

Categories테이블에는 다섯 가지 범주가 있습니다.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 아이디 | 이름 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 1 | 스포츠 |
| 2 | 뉴스 |
| 3 | 엔터테인먼트 |
| 4 | 기술 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Users테이블에는 두 명의 사용자가 있습니다.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 아이디 | 이름 |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| 1 | UserA |
| 2 | UserB |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

UserA는 자신의 카테고리로 스포츠 및 기술을 선택할 수 있습니다.

UserB는 뉴스, 스포츠 및 엔터테인먼트를 선택할 수 있습니다.

스포츠 카테고리가 삭제되고 UserA 및 UserB 카테고리 목록 모두 삭제가 반영됩니다.

나는 UserCategories카테고리와 사용자 모두의 ID를 보유 하는 테이블을 만드는 데 놀랐다 . 이런 종류의 작업은 카테고리 이름을 찾을 수 있지만 계단식 삭제가 작동하지 않고 전체 솔루션이 잘못된 것처럼 보였습니다.

내가 찾은 belongs_to 및 has_many 함수를 사용하는 예는 일대일 관계 매핑을 논의하는 것 같습니다. 예를 들어, 블로그 게시물에 대한 댓글입니다.

  • 내장 된 Rails 기능을 사용하여 이러한 다 대다 관계를 어떻게 표현합니까?
  • Rails를 사용할 때 둘 사이에 별도의 테이블을 사용하는 것이 실행 가능한 솔루션입니까?

당신은 has_and_belongs_to_many관계를 원합니다 . 이 가이드는 이것이 차트와 모든 것에서 어떻게 작동하는지 설명하는 훌륭한 작업을 수행합니다.

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

다음과 같은 결과를 얻게됩니다.

# 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

이제 Rails에서 사용할 조인 테이블을 만들어야합니다. Rails는이 작업을 자동으로 수행하지 않습니다. 이는 사실상 각 범주 및 사용자에 대한 참조가있는 테이블이며 기본 키는 없습니다.

다음과 같이 CLI에서 마이그레이션을 생성합니다.

bin/rails g migration CreateCategoriesUsersJoinTable

그런 다음 열어서 일치하도록 편집하십시오.

Rails 4.0.2+ (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

레일스 <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?

The most popular is 'Mono-transitive Association', you can do this:

class Book < ApplicationRecord
  has_many :book_author
  has_many :author, through: :book_author
end

# in between
class BookAuthor < ApplicationRecord
  belongs_to :book
  belongs_to :author
end

class Author < ApplicationRecord
  has_many :book_author
  has_many :book, through: :book_author
end

A has_many :through association is often used to set up a many-to-many connection with another model. This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding through a third model. For example, consider a medical practice where patients make appointments to see physicians. Ref.: https://guides.rubyonrails.org/association_basics.html#the-has-many-through-association


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.

참고URL : https://stackoverflow.com/questions/5120703/creating-a-many-to-many-relationship-in-rails

반응형