扶手:随着车型其中B属于C和B A的has_many乙belongs_to的Ç回报A的最近创建的用于给的?

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

我有三种型号A,B,和C,其中A has_many B; B belongs to CB has a created_on timestamp。通过B C的has_many甲

我想返回的其中A具有属于C与B中的所有的A其中B是对于A的最近创建的乙

我可以用方法循环执行此操作。这能与named_scopes唯一目的?或者是一些其他的优雅/有效的方式?

根据要求对现实世界(TM)实施例A,B和C可以被想象成,例如,宠物(A),PetsName(B),和名称(C)。 PetsNames给予宠物在特定的时间和任何给定的名称可以给许多宠物。任何宠物可以有许多名字(答:通过关系)。对于给定的名称我想的宠物中,该名称是该宠物最近创建PetName的所有。呼叫可能看起来像@name.pets.most_recently_named_as

有帮助吗?

解决方案

Rails的方式做到这一点是在宠物命名范围。

像这样:

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的方法/调用指定的范围名称。

您总是可以做

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

这是一个相当复杂的加入。这是你应该应该反思一下,你存储这些信息的方式的一个指标。为什么如此重要的是名称是在一个单独的表?

您可能会更好做这样的事情:

添加nameold_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