В RoR, как мне создать ДВА отношения один к одному между двумя таблицами? - PullRequest
1 голос
/ 27 декабря 2010

В RoR3,

У меня есть пользователи и навыки, и каждый навык создается пользователем. Я хотел это записать, поэтому создал отношения один ко многим.

class User < ActiveRecord::Base
  has_many :skills
end

class Skill < ActiveRecord::Base
  belongs_to :user
end

Однако, у каждого пользователя также есть много навыков в том смысле, что пользователь "Боб" создал навык "Кунг-фу", пользователь "Чарли" создал навык "Каратэ", а пользователь "Боб" создал и может делать оба " Кунг-фу "и" Каратэ "

Как мне представить это с ActiveRecord? Должен ли я просто создать новую таблицу user_skills, которая имеет has_many: skill? и принадлежать_пользователю?

Ответы [ 3 ]

4 голосов
/ 27 декабря 2010

Здесь есть две разные ассоциации. Первая - это ассоциация «один ко многим». Пользователь может быть создателем любого количества умений. Вторая ассоциация «многие ко многим», у пользователя может быть много навыков, а у навыка может быть много пользователей.

Первая - это простая belongs_to <-> has_many декларация. Для второго вам понадобится либо объявление has_and_belongs_to_many в обеих моделях и соответствующая таблица соединений, либо выделенная модель соединения, а также объявление has_many :through. Давайте попробуем первый:

Метод 1: HABTM

class User < ActiveRecord::Base
  has_many :created_skills, :class_name => 'Skill', :inverse_of => :creator
  has_and_belongs_to_many :skills
end

class Skill < ActiveRecord::Base
  belongs_to :creator, :class_name => 'User', :inverse_of => :created_skills
  has_and_belongs_to_many :users
end

Для этого требуется таблица соединений с названием «skill_users», в которой есть столбцы с именами user_id и skill_id

Метод 2: Проходит много (Присоединиться к модели)

Второй аналогичен, но добавляет модель, которая действует как посредник. Это дает дополнительное преимущество, заключающееся в том, что вы можете включить дополнительные столбцы в модель объединения, например, уровень квалификации.

class User < ActiveRecord::Base
  has_many :created_skills, :class_name => 'Skill', :inverse_of => :creator
  has_many :user_skills
  has_many :skills, :through => :user_skills
end

class Skill < ActiveRecord::Base
  belongs_to :creator, :class_name => 'User', :inverse_of => :created_skills
  has_many :user_skills
  has_many :users, :through => :user_skills
end

class UserSkill < ActiveRecord::Base
  belongs_to :user
  belongs_to :skill
end
1 голос
/ 27 декабря 2010

Имея эти две модели

class User < ActiveRecord::Base 
   has_and_belongs_to_many :skills
 end

 class Skill < ActiveRecord::Base  
   has_and_belongs_to_many :users
 end

Вы должны будете создать дополнительную миграцию (без модели)

 rails generate migration CreateSkillsUsersJoin 

, которая даст вам

     class CreateSkillsUsersJoin < ActiveRecord::Migration
         def self.up
            create_table :skills_users, id => false do |t|
                t.references "user"
                t.references "skill"
             end
             add_index :skills_users,["user_id","skill_id"]
         end
         def self.down
            drop_table :skills_users
         end
      end

Методы self.up и self.down вы можете добавить их

0 голосов
/ 27 декабря 2010

Вы бы хорошо обслужили, используя драгоценный камень, такой как acts_as_taggable_on , который вы могли бы просто настроить и использовать в своей модели пользователя, что-то вроде:

acts_as_taggable_on :skills

Честно говоря, они разобрались со всем этим, так как это не так просто, как то, что ты пытаешься сделать, ИЛИ Я должен перефразировать это и сказать, что то, что ты пытаешься сделать, явно «сложно», и этот камень позволяет вам просто продолжать, продолжать после того, как это настроено.

Прочитайте файл Readme.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...