1

has_many让一个模型同时具有 a和 ahas_one关系的正确(Rails)方式是什么?在我的例子中,我希望我的Device模型同时跟踪它的当前位置和它之前的所有位置。这是我的尝试,它很实用,但有更好的方法吗?

楷模

class Location < ActiveRecord::Base
  belongs_to :device
end

class Device < ActiveRecord::Base
  has_many :locations # all previous locations
  belongs_to :location # current location
end
4

5 回答 5

0
class Device < ActiveRecord::Base
  has_and_belongs_to_many :locations
end
于 2012-05-29T04:27:25.733 回答
0

好吧,Rails 的方式是您可以创建许多您喜欢的关联。您也可以根据您的逻辑命名您的关联。只需将:class_name选项传递给您的关联逻辑。

class Location < ActiveRecord::Base
  belongs_to :device
end

class Device < ActiveRecord::Base
  has_many :previous_locations,
           :class_name => "Location",
           :conditions => ["locations.created_at < ?", DateTime.now]
  has_one  :location,
           :class_name => "Location",
           :conditions => ["locations.created_at = ?", DateTime.now]
end
于 2012-05-29T04:33:08.607 回答
0

在“Active Record 关联指南”中,我推荐阅读第 2.8 节:在 has_many :through 和 has_and_belongs_to_many 之间进行选择

最简单的经验法则是,如果您需要将关系模型作为独立实体使用,则应该设置一个 has_many :through 关系。如果您不需要对关系模型做任何事情,那么设置 has_and_belongs_to_many 关系可能会更简单(尽管您需要记住在数据库中创建连接表)。

如果您需要验证、回调或连接模型上的额外属性,您应该使用 has_many :through。

http://guides.rubyonrails.org/association_basics.html#choosing-between-has_many-through-and-has_and_belongs_to_many

于 2012-05-29T04:34:34.317 回答
0
class Location < ActiveRecord::Base
  belongs_to :device
end

class Device < ActiveRecord::Base
  has_many  :locations

  def previous_locations
    self.locations.order('created_at asc').limit( self.locations.count-1)
  end

  def current_location # or last_location
    self.locations.order('created_at desc').limit(1)
  end

  # you may like to add this one
  def current_location= args
    args = Location.new args unless args.is_a? Location
    self.locations << args
  end
end

请注意,所有 @device.locations、@device.previous_locations 和 @device.current_location 都将返回 ActiveRecord::Relation

于 2012-05-29T06:45:59.937 回答
0
class Location < ActiveRecord::Base
  belongs_to :device
  has_one :current_location, :class_name => 'Device',
                              :conditions => { :active => true }
end

class Device < ActiveRecord::Base
  has_many :locations # all previous locations
end

位置有一个名为“活动”的布尔字段,您将其设置为真/假。

于 2012-05-29T12:48:20.447 回答