2011-02-09 62 views
2

我正在尝试创建一个用于在ActiveRecord集合中创建重定向对象的factory_build类方法(请参见下文)。ActiveRecord集合和自定义方法

例如@ website.redirects.factory_build(:code => 301)将返回一个PermenantRedirect对象的新实例。但是,即使我能够调用factory_build类方法,我也无法访问@ web站点的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

您能详细阐述一下`Website`和`Redirect`的关系和功能吗? Redirect的不同子类有不同的功能,还是代码的范围? – 2011-02-09 01:17:59

回答

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 }之类的形式出现,并可以传递给您的创建呼叫。

+0

在rails 3升级的过程中,会不会碰巧知道如何在Rails 2.3.4中做到这一点?虽然很好的答案!让我走上正轨。谢谢! – rramsden 2011-02-09 04:18:58