为什么我不断收到此 ActiveRecord::AssociationTypeMismatch 错误?

Why do I keep getting this ActiveRecord::AssociationTypeMismatch error?

我有两个模型与同一对象有 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

除非您正在进行某种多态性(没有记录在案),否则我会尝试更改此设置:

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 gem 对此很有用),或者更简单地作为 User 模型上的布尔值。

我认为你想对我们做的完全是错误的。管理员也是用户。您应该完全删除 Admin 模型。如果您需要为某人分配额外的能力/权限,您应该创建一个额外的属性(admin boolean yes/no),或者创建某种基于角色的模型。看看 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

不过有一个警告....用户是强制性的是这种关系,所以如果有人没有登录,这将会中断!考虑一下...要么不创建访问,要么创建匿名访问。