我正在尝试创建一个factory_build类方法,用于在ActiveRecord集合中创建Redirect对象(参见下文)。
例如 @ website.redirects.factory_build(:code => 301)会返回PermenantRedirect对象的新实例。但是,即使我能够调用factory_build类方法,我也无法访问@website的primary_key。有没有办法从集合内部访问@ website.id或者我被迫将其传递给方法调用?任何其他建议也会受到欢迎,也许我不会用正确的方法来解决这个问题。感谢。
class Website < ActiveRecord::Base
has_many :redirects
has_many :permenant_redirects
has_many :temporary_redirects
end
# Redirect is an abstract class it uses Rails Single Table Inheritance
class Redirect < ActiveRecord::Base
def self.factory_build(attributes)
status_code = attributes.delete(:code)
case status_code
when 301
Website.find( ... ).permenant_redirects.new(attributes)
when 302
Website.find( ... ).temporary_redirects.new(attributes)
else
raise InvalidStatusCodeError
end
end
end
class TemporaryRedirect < Redirect
def status
302
end
end
class PermenantRedirect < Redirect
def status
301
end
end
答案 0 :(得分:0)
您需要访问此关系的范围才能正确构建这些对象。这可用于类方法:
class Redirect < ActiveRecord::Base
def self.factory_build(attributes)
redirect_type =
case (status_code = attributes.delete(:code))
when 301
PermanentRedirect
when 302
TemporaryRedirect
else
Redirect
end
redirect_type.new(attributes.merge(scoped.scope_for_create))
end
end
我冒昧地干掉你的创作代码,因为那里有很多重复。另请注意,仅仅为了执行关系而调用find
会浪费资源。如果您知道记录的ID,只需将其作为属性传递,除非您有充分的理由首先检索它。
scoped.scope_for_create
调用返回当前范围或范围定义的属性。这些通常采用{ 'website_id' => 101 }
之类的形式,可以传递给您的创建调用。