为什么我不断收到此 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
不过有一个警告....用户是强制性的是这种关系,所以如果有人没有登录,这将会中断!考虑一下...要么不创建访问,要么创建匿名访问。
我有两个模型与同一对象有 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
不过有一个警告....用户是强制性的是这种关系,所以如果有人没有登录,这将会中断!考虑一下...要么不创建访问,要么创建匿名访问。