2011-02-09 2 views
2

ActiveRecord 컬렉션 (아래 참조) 내에서 리디렉션 개체를 만들기위한 factory_build 클래스 메서드를 만들려고합니다.ActiveRecord 컬렉션 및 사용자 정의 메서드

예 : @ 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

'웹 사이트'와 '리디렉션'의 관계와 기능에 대해 자세히 설명해 주시겠습니까? 'Redirect'의 다른 하위 클래스는 다른 기능을 가지고 있습니까? 아니면 코드의 범위입니까? –

답변

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를 아는 경우 먼저 레코드를 검색해야하는 매우 좋은 이유가 없으면 레코드의 ID를 특성으로 전달하십시오.

scoped.scope_for_create 호출은 현재 범위 또는 범위로 정의 된 특성을 반환합니다. 이들은 일반적으로 { 'website_id' => 101 }과 같은 형식으로 작성 호출에 전달 될 수 있습니다.

+0

레일 3 업그레이드 중에, 레일즈 2.3.4에서 이것을 수행하는 방법을 알지 못하겠습니까? 좋은 대답! 바른 길에 나를 놓아 라. 고맙습니다! – rramsden

+0

레일 2의 경우'scoped.scope_for_create' 대신'scope (: create)'를 사용해야 할 수도 있습니다. – tadman

관련 문제