Почему я получаю эту ошибку ActiveRecord :: AssociationTypeMismatch? - PullRequest
0 голосов
/ 08 февраля 2019

У меня есть две модели, которые имеют связь has_many с одним и тем же объектом.У меня есть Пользователь, Администратор и Посещения.

Пользователи has_many Посещения Администраторы has_many Посещения

Каждый раз, когда я создаю Посещение с Пользователем, это работает, но когда я делаю это с Администратором этовыдает ошибку:

ActiveRecord::AssociationTypeMismatch.

Полная ошибка такова:

User(#70282715553200) expected, got #<Admin id: 2, email: "admin@gmail.com", created_at: "2019-02-07 12:08:40", updated_at: "2019-02-07 12:08:40"> which is an instance of Admin(#70282709528720)

def create
  @visit = @service.visits.new(visit_params)

  if user_signed_in?
    @visit.user = current_user
  else
    @visit.user = current_admin
  end

  if @visit.save
    redirect_to service_visits_path(@service)
  else
    redirect_to @services
  end

end

==============================

class Admin < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and 
  # :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable

  has_many :visits, dependent: :destroy
end

==============================

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and 
  #  :omniauthable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :validatable

  has_many :visits, dependent: :destroy
end

==============================

class Visit < ApplicationRecord
  belongs_to :user
  belongs_to :admin
  belongs_to :service
end

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Я думаю, что вы пытаетесь сделать нас просто неправильно.Админ тоже пользователь.Вы должны полностью удалить модель Admin.Если вам нужно назначить кому-то дополнительные возможности / права, вы должны либо создать дополнительный атрибут (логическое имя администратора да / нет), либо создать какую-либо модель на основе ролей.Взгляните на Rolify gem.

class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and 
:omniauthable
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :validatable

  has_many :visits, dependent: :destroy

  def is_admin?
    // return true if user is admin
  end
 end

class Visit < ApplicationRecord
  belongs_to :user
  belongs_to :service
end

def create
@visit = @service.visits.new(visit_params)

if user_signed_in?
  @visit.user = current_user
else

if @visit.save
  redirect_to service_visits_path(@service)
else
  redirect_to @services
end

Одно предупреждение, хотя .... пользователь обязателен, если это отношение, поэтому оно разорвется, если кто-то не вошел в систему!Подумайте об этом ... либо не создавайте посещение, либо создавайте анонимное посещение.

0 голосов
/ 08 февраля 2019

Если у вас не происходит какой-то полиморфизм, который не задокументирован, я бы попытался изменить это:

if user_signed_in?
  @visit.user = current_user
else
  @visit.user = current_admin
end

На это:

if user_signed_in?
  @visit.user = current_user
else
  @visit.admin = current_admin # this line
end

Ваша модель Visit говорит, что у посещения есть и один User, и один Admin, поэтому вы должны назначить current_admin для @visit.admin, а не @visit.user.

Если вы используете Rails 5, вам также необходимо обновить вашу модель, как показано ниже:

class Visit < ApplicationRecord
  belongs_to :user, optional: true
  belongs_to :admin, optional: true
  belongs_to :service
end

Как я заметил в моем комментарии ниже, предложение от @ bo-ozследует уделить значительное внимание.Я не видел таблиц User и Admin, которые обычно разделяются, как вы это делали в производственных приложениях.Концепция 'admin' обычно обрабатывается как отдельная модель Role (для этого хорошо подходит rolify), или, проще, как логическое выражение в модели User.

...