Полиморфное has_many через ассоциации в Ruby on Rails - PullRequest
0 голосов
/ 08 мая 2018

У меня следующая проблема, У пользователя может быть несколько профессий, более 10. Например, пользователь может быть врачом, учителем и N. У каждой профессии есть свои атрибуты. Я мог бы, Доктор, принадлежит_Пользователю, но если я хочу узнать все профессии этого пользователя, мне придется проверить каждую строку таблицы "Пользователь".

Я создал следующий код

class User < ApplicationRecord
  has_many :jobables
end

class Job < ApplicationRecord
  belongs_to :user
  belongs_to :jobable
end

class Jobable < ApplicationRecord
  has_one :job
end

class Medic < Jobable
end

class Programmer < Jobable
end

Но я не знаю, будет ли это лучшим ответом

1 Ответ

0 голосов
/ 08 мая 2018

Я думаю, что было бы намного проще сделать что-то вроде:

class User < ApplicationRecord
  has_many :user_professions
  has_many :professions, through: :user_professions
end

# == Schema Information
#
# Table name: professions
#
#  id                     :integer          not null, primary key
#  name                   :string
#  created_at             :datetime         not null
#  updated_at             :datetime         not null
#
class Profession < ApplicationRecord
  has_many :user_professions
  has_many :users, through: :user_professions
end

class UserProfession < ApplicationRecord
  belongs_to :user 
  belongs_to :profession 
end

Затем можно создать логику, чтобы гарантировать, что Profession назначается только User один раз.

Тогда вы можете просто сделать:

@user.professions

И получите все Profession с за User.

Вы также можете сделать:

@profession.users 

И получить все User с Profession.

Исходя из редактирования вашего вопроса, вы могли бы сделать что-то вроде:

class UserProfession < ApplicationRecord
  belongs_to :user 
  belongs_to :profession
  belongs_to :profession_detail, polymorphic: true
end

В этом случае у вас может быть что-то вроде:

class DoctorDetail < ApplicationRecord
end

И вы могли бы сделать что-то вроде:

@user.professional_detail_for(:doctor)

Конечно, вам нужно реализовать метод professional_detail_for для модели User, который может выглядеть примерно так:

class User < ApplicationRecord 
  has_many :user_professions
  has_many :professions, through: :user_professions

  def professional_detail_for(profession_type)
    user_profession_for(profession_for(profession_type)).try(:profession_detail)
  end

private

  def profession_for(profession_type)
    Profession.find_by(name: profession_type.to_s)
  end

  def user_profession_for(profession)
    user_professions.find_by(profession: profession)
  end

end

Это немного грубо, но я думаю, вы поняли.

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