I’m trying to create a factory_build class method for creating Redirect objects within an ActiveRecord collection (see below).
For example @website.redirects.factory_build(:code => 301) would return a new instance of a PermenantRedirect object. However, even though I am able to invoke the factory_build class method I can’t get access to the primary_key for @website. Is there a way to access @website.id from inside a collection or am i forced to pass it into the method call? Any other suggestions would also be welcome, maybe I’m not going about this in the right approach. thanks.
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
You need to access the scope for this relationship in order to be able to properly construct these objects. This is available to a class method:
I’ve taken the liberty of DRYing up your creation code because you had a lot of duplication in there. Also note that calling
findonly to exercise a relationship is a waste of resources. If you know the ID of the record, simply pass that along as an attribute unless you have a very good reason for retrieving it first.The
scoped.scope_for_createcall returns attributes defined by your current scope or scopes. These are usually in the form of something like{ 'website_id' => 101 }and can be passed through to your create call.