레일 : 모델을 사용하면 a has_many b boogles_to c는 b에 속하는 곳에 b를 반환하고 b는 c에 속하고 b는 가장 최근에 주어진 a에 만들어 졌습니까?

StackOverflow https://stackoverflow.com/questions/2247257

문제

세 가지 모델 A, B 및 C가 있습니다. A has_many B; B belongs to C, 그리고 B has a created_on timestamp. C has_many a ~ B.

나는 돌아오고 싶다 모두 A는 A가 C에 속한 B가 있고 B는 A에 가장 최근에 생성 된 B입니다.

메소드 루프 로이 작업을 수행 할 수 있습니다. 이것은 명명 된 _scopes로만 할 수 있습니까? 아니면 다른 우아하고 효율적인 방법입니까?

실제 세계 (TM) 예제 A, B 및 C는 예를 들어 애완 동물 (a), 애완 동물 (b) 및 이름 (c)으로 상상할 수 있습니다. 애완 동물은 특정 시간에 애완 동물에게 제공되며, 많은 애완 동물에게 주어진 이름이 주어질 수 있습니다. 모든 애완 동물은 많은 이름을 가질 수 있습니다 (A : 관계를 통해). 주어진 이름으로 원하는 이름 모두 그 이름이 그 애완 동물의 가장 최근에 만든 페트 이름 인 애완 동물 중. 전화는 같은 것처럼 보일 수 있습니다 @name.pets.most_recently_named_as

도움이 되었습니까?

해결책

이 작업을 수행하는 레일 방법은 애완 동물의 이름이 지정된 범위입니다.

이 같은:

class Pets
  has_many :pet_names
  has_many :names, :through => :pet_names

  named_scope :with_current_name, lambda {|name| 
    { :joins => "JOIN (pet_names pna, names) " +
        "ON (pna.pet_id = pets.id AND pna.name_id = names.id) " +
        "LEFT JOIN pet_names pnb " +
        "ON (pnb.pet_id = pets.id AND pna.created_at < pnb.created_at)", 
      :conditions => ["pnb.id IS NULL AND names.id = ? ", name]
    }
  }
end

Pets.with_current_name(@name)
@name.pets.with_current_name(@name)

이름을 중심으로 유지하려면 항상 C/Name의 메소드를 명명 된 범위를 호출 할 수 있습니다.

당신은 항상 할 수 있습니다

class Name < ActiveRecord::Base
  has_many :pet_names
  has_many :pets, :through => :pet_names

  def currently_named_pets
    Pets.with_current_name(self)
  end
end

그리고

@name.currently_named_pets

그것은 꽤 복잡한 가입입니다. 이 정보를 저장하는 방식을 다시 생각해야한다는 지표입니다. 이름이 별도의 테이블에있는 것이 왜 그렇게 중요한가?

다음과 같은 일을하는 것이 더 나을 수 있습니다.

추가 후 name 그리고 old_name 애완 동물의 열 :

class Pet < ActiveRecord::Base
  serialize :old_name, Array
  def after_initialization 
    @old_name ||= []
  end

  def name= new_name
    self.old_name << new_name
    self.name = new_name
  end

  named_scope :with_name, lambda {|name|
     { :conditions => {:name => name}}
  }
end
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top