如何使普通 ruby 对象可分配为活动记录关联
How to make a plain ruby object assignable as active record association
我有一个由 ActiveRecord 支持的 Audit
class。
class Audit < ActiveRecord::Base
belongs_to :user, polymorphic: true
end
我有一个 User
class,它是一个包含一些 ActiveModel 功能的普通 ruby 对象。它不是数据库模型,因为我的用户实际上存储在不同的数据库中并通过 API.
提供服务
class User
include ActiveModel::Conversion
include ActiveModel::Validations
extend ActiveModel::Naming
def self.primary_key
'id'
end
def id
42
end
def persisted?
false
end
end
我正在尝试将用户分配给这样的审核:
audit = Audit.new
audit.user = User.new
audit.save!
从数据的角度来看,这应该没问题。要定义多态关联,我们需要将值放入审计 table 的两列中。我们可以将 audits.user_id
设置为值 42
并将 audits.user_type
设置为字符串 "User".
但是,我遇到了一个异常:
undefined method `_read_attribute' for #<User:0x007f85faa49520 @attributes={"id"=>42}> (NoMethodError)
active_record/associations/belongs_to_polymorphic_association.rb:13:in `replace_keys'
我追溯到 ActiveRecord
来源,它似乎被定义为 here。不幸的是,它是 ActiveRecord
而不是 ActiveModel
的事实意味着我不能将该 mixin 包含到我的 class.
我尝试定义自己的 _read_attribute
方法,但我陷入了困境,不得不重新定义越来越多的 ActiveRecord 功能,例如 AttributeSet 等等。
我还意识到我可以通过分配 Audit#user_type
和 Audit#user_id
来解决这个问题。然而,这并不令人满意,因为实际上,我必须分叉 gem 并对其进行编辑才能做到这一点。
如何修改我的用户 class 以便我可以将其完全分配给审核。
P.S。 Here's a sample app 所以你可以自己试试。
与其越来越深入地复制 ActiveRecord
功能,不如考虑实际继承 ActiveRecord::Base
而不是包含 ActiveModel
。您唯一的限制是您没有 table。有一个 gem:
此 class 适用于您的示例应用:
require 'active_record'
require 'activerecord-tableless'
class User < ActiveRecord::Base
has_no_table
# required so ActiveRecord doesn't try to create a new associated
# User record with the audit
def new_record?
false
end
def id
42
end
end
我有一个由 ActiveRecord 支持的 Audit
class。
class Audit < ActiveRecord::Base
belongs_to :user, polymorphic: true
end
我有一个 User
class,它是一个包含一些 ActiveModel 功能的普通 ruby 对象。它不是数据库模型,因为我的用户实际上存储在不同的数据库中并通过 API.
class User
include ActiveModel::Conversion
include ActiveModel::Validations
extend ActiveModel::Naming
def self.primary_key
'id'
end
def id
42
end
def persisted?
false
end
end
我正在尝试将用户分配给这样的审核:
audit = Audit.new
audit.user = User.new
audit.save!
从数据的角度来看,这应该没问题。要定义多态关联,我们需要将值放入审计 table 的两列中。我们可以将 audits.user_id
设置为值 42
并将 audits.user_type
设置为字符串 "User".
但是,我遇到了一个异常:
undefined method `_read_attribute' for #<User:0x007f85faa49520 @attributes={"id"=>42}> (NoMethodError)
active_record/associations/belongs_to_polymorphic_association.rb:13:in `replace_keys'
我追溯到 ActiveRecord
来源,它似乎被定义为 here。不幸的是,它是 ActiveRecord
而不是 ActiveModel
的事实意味着我不能将该 mixin 包含到我的 class.
我尝试定义自己的 _read_attribute
方法,但我陷入了困境,不得不重新定义越来越多的 ActiveRecord 功能,例如 AttributeSet 等等。
我还意识到我可以通过分配 Audit#user_type
和 Audit#user_id
来解决这个问题。然而,这并不令人满意,因为实际上,我必须分叉 gem 并对其进行编辑才能做到这一点。
如何修改我的用户 class 以便我可以将其完全分配给审核。
P.S。 Here's a sample app 所以你可以自己试试。
与其越来越深入地复制 ActiveRecord
功能,不如考虑实际继承 ActiveRecord::Base
而不是包含 ActiveModel
。您唯一的限制是您没有 table。有一个 gem:
此 class 适用于您的示例应用:
require 'active_record'
require 'activerecord-tableless'
class User < ActiveRecord::Base
has_no_table
# required so ActiveRecord doesn't try to create a new associated
# User record with the audit
def new_record?
false
end
def id
42
end
end