Полиморфная ассоциация не работает

В моем приложении rails 3.2 у меня есть модель пользователя и модель врача со следующими полиморфными ассоциациями:

Пользователь

class User < ActiveRecord::Base
  attr_accessible :authenticatable_id, :authenticatable_type, :email
  belongs_to :authenticatable, polymorphic: true
end

Врач

class Physician < ActiveRecord::Base
  attr_accessible :name
  has_one :user, as: :authenticatable
end

Я хотел проверить это в консоли и столкнулся со странной вещью. Делает:

p = Physician.new
p.user.build

дает мне NoMethodError: undefined method 'build' for nil:NilClass - но почему пользовательский атрибут врача должен быть nil?

Странно, когда я меняю модель врача на has_many :users вместо has_one :user и делаю

p = Physician.new
p.users.build

все работает нормально.

Чего мне не хватает, чтобы заставить ассоциацию has_one работать?


person weltschmerz    schedule 27.01.2013    source источник
comment
Вероятно, вам следует сделать p.build_user, так как has_one не добавляет метод .build   -  person Vadim Chumel    schedule 27.01.2013
comment
@VadimChumel Круто, это именно то, что мне было нужно! Пожалуйста, добавьте это как ответ, чтобы я мог принять и проголосовать за него :-)   -  person weltschmerz    schedule 27.01.2013


Ответы (2)


Вероятно, вам следует сделать p.build_user, так как has_one не добавляет метод association.build. Вы также можете проверить apidock о методах has_one и has_many «внедряет» в вашу модель.

person Vadim Chumel    schedule 27.01.2013

Мне не совсем понятно, но кажется, что вы создаете Physician, который также является User. Таким образом, он может использовать функции, которые предоставляет User.

Ваша реализация создает два объекта: один Physician и одинUser, но, если строго смотреть на ситуацию, оба являются одним и тем же врачом/пользователем.

Поэтому вы должны позволить Physician наследовать от User:

class Physician < User

и удалите полиморфную связь между Physician и User.

person Veger    schedule 27.01.2013
comment
Спасибо за Ваш ответ! Я использую пользовательскую модель Devise, и мне просто нужны разные роли пользователей. Например, есть не только врач, но позже может быть и аптека и т. д., но все они пользователи. Итак, я думаю, что полиморфная ассоциация - правильный подход, мне просто нужно, чтобы ассоциация работала... Есть идеи? - person weltschmerz; 27.01.2013
comment
Роли могут быть реализованы с использованием наследования. Например, class Pharmacy < User также допустимо. Если только вы не получите пользователей с несколькими ролями одновременно... - person Veger; 27.01.2013