Связь Ruby on Rails has_many.

Я новичок в RoR и работаю над своим первым проектом. Основная концепция этой идеи состоит в том, чтобы связать «Пользователей», выбравших набор «Навыки», с другими Пользователями, которые отправили «Запрос на помощь», относящийся конкретно к этим выбранным навыкам. Приложение, которое связывает опытных пользователей с пользователями, которым нужна помощь, если хотите. Мой вопрос связан с отношениями между моделями Users, Skills и Help_Request. Похоже, что для такого рода трехсторонних отношений может подойти «ассоциация has_many:through» или, может быть, «полиморфная ассоциация»? Правда не уверен?

Любые мысли или предложения будут очень признательны.


person Flint285    schedule 07.11.2013    source источник
comment
Простейшей структурой будет HABTM между пользователями/навыками и HelpRequest/навыками, к которым вы затем присоединитесь.   -  person Damien Roche    schedule 07.11.2013


Ответы (3)


Боюсь, ответа ShivamD будет недостаточно. Для этого потребуется дублировать Skills и запросить соответствующее отношение User.help_requests через, где вместо этого вам нужно пересечение.

Мало того, Users, создавшие HelpRequests, уже будут иметь отношения has_many. Это имеет смысл.

Я не буду включать схему для HABTM, которую собираюсь предложить (см. здесь), но я расскажу о моделях. По сути, что вы хотите:

skill = Skill.create(name: "My Skill")
user.skills         << skill
help_request.skills << skill

user.matched_help_requests
#> [help_request]

Что может быть достигнуто следующим образом:

class User
  has_and_belongs_to_many :skills

  def matched_help_requests
    HelpRequest.joins(:skills).where("skills.id IN(?)", skills.pluck(:id))
  end
end

class HelpRequest
  has_and_belongs_to_many :skills
end

class Skill
  has_and_belongs_to_many :users
  has_and_belongs_to_many :help_requests
end

РЕДАКТИРОВАТЬ: вот схема для HABTM:

rails g migration add_skills_join_tables

в рамках миграции

def change
  create_table :skills_users, id: false do |t|
    t.references :skill
    t.references :user
  end

  create_table :help_requests_skills, id: false do |t|
    t.references :skill
    t.references :help_request
  end

  add_index :skills_users,        [:skill_id, :user_id]
  add_index :help_request_skills, [:skill_id, :help_request_id] 
end
person Damien Roche    schedule 07.11.2013
comment
Просто для уточнения. Когда я настраиваю свои отношения HABTM, я создаю одну или две таблицы соединения без первичного ключа? (как указано в документации) Кроме того, не могли бы вы немного подробнее объяснить метод matched_help_request? Большое спасибо, Дэмиен, я очень ценю это. - person Flint285; 08.11.2013
comment
@ Flint285 Вам потребуются две таблицы соединения. Смотрите ответ тиаготекса. Две таблицы, которые вам понадобятся, это skills_users и help_requests_skills, и ни одна из них не имеет первичного ключа, но у них есть индексы. Я обновлю свой ответ, чтобы показать миграцию. - person Damien Roche; 08.11.2013
comment
@ Flint285 обновленный ответ. Метод matched_help_request можно было бы улучшить. Это собирает идентификаторы навыков пользователя с помощью таблицы соединений skills_users (skills.pluck(:id)), а затем выполняет запрос на соединение, в котором совпадают идентификаторы навыков HelpRequest. - person Damien Roche; 08.11.2013
comment
Хорошо, мои схемы и модели готовы к работе. Не могли бы вы немного подробнее объяснить метод Skill.create и то, как он вписывается в контроллер и представление? Как обычно, большое спасибо Дэмиену. - person Flint285; 09.11.2013

Полиморфная ассоциация — это когда модель должна принадлежать другой модели. Скажем, когда вы комментируете модель. Вы можете комментировать пост и сам комментарий. Вот тогда вы бы использовали полиморфный.

В вашем случае подойдет простой has_many. Это должно выглядеть так

class User < ActiveRecord::Base 
  has_many :skills 
  has_many :help_requests, through: :skills
end

class Skill < ActiveRecord::Base 
  belongs_to :user
  belongs_to :helpRequest
end

class HelpRequest < ActiveRecord::Base 
  has_many :skills 
  has_many :users, through :skills
end

Дополнительную информацию можно найти в документах.

person ShivamD    schedule 07.11.2013

Один из способов — создать has_and_belongs_to_manyотношение между пользователями, запросами помощи и навыками, так что в итоге вы получите следующее:

class User < ActiveRecord::Base
  has_and_belongs_to_many :skills
end

class Help_request < ActiveRecord::Base
  has_and_belongs_to_many :skills
end

class Skills < ActiveRecord::Base
      has_and_belongs_to_many :users
      has_and_belongs_to_many :help_requests
end

Затем вам нужно создать таблицы

 rails g migration add_skills_users_table

 rails g migration add_help_requests_skills_table

В конце запустите rake db:migrate

Затем вы можете найти его, используя User.first.skills

person tiagotex    schedule 07.11.2013
comment
Просто для уточнения. Когда я настраиваю свои отношения HABTM, я создаю одну или две таблицы соединения без первичного ключа? - person Flint285; 08.11.2013