我有两种类型的活动记录(对象):
1。项目
<Project:0x007fd1b3ef3c10
id: 1,
min_price: 1000,
max_price: 2000>
2。财产
<Property:0x007fd1b3ef3c15
id: 1,
price: 1000>
他们在一个阵列[项目,财产,项目等..]
我需要按price
对它们进行排序,但如果是项目类型,那么我应该使用min_price
。我可以在铁轨上做到这一点吗?
我曾尝试使用sort_by
,但无法正常工作。
示例
[
<project id:1, min_price:1, max:price:100>,
<property id:2, price:5>,
<project id:3, min_price:3, max:price:100>,
]
我希望它返回:
[
<project id:1, min_price:1, max:price:100>,
<project id:3, min_price:3, max:price:100>,
<property id:2, price:5>,
]
答案 0 :(得分:1)
您有多种选择:为这两个模型定义一个通用方法,或者只使用sort_by
一个动态决定用于排序的方法的块。看看这个片段:
class Project
attr_accessor :min_price
alias_method :sort_price, :min_price
def initialize(min_price)
@min_price = min_price
end
end
class Property
attr_accessor :price
alias_method :sort_price, :price
def initialize(price)
@price = price
end
end
collection = [Project.new(10), Property.new(20), Project.new(5), Property.new(7)]
puts collection.sort_by(&:sort_price).inspect
puts(collection.sort_by do |record|
record.is_a?(Project) ? record.min_price : record.price
end.inspect)
我个人更喜欢使用常用方法的解决方案,因为它更面向对象(遵循多态)。如果你不喜欢污染你的模型,你可以做一个装饰器进行分类:
class SortingItem
attr_reader :object
def initialize(object)
@object = object
end
def sort_price
case @object
when Project
@object.min_price
when Property
@object.price
else
fail ArgumentError, "unknown sorting item - #{object.class}"
end
end
end
class Project
attr_accessor :min_price
def initialize(min_price)
@min_price = min_price
end
end
class Property
attr_accessor :price
def initialize(price)
@price = price
end
end
def decorate(object)
SortingItem.new(object)
end
collection = [decorate(Project.new(10)), decorate(Property.new(20)), decorate(Project.new(5)), decorate(Property.new(7))]
puts collection.sort_by(&:sort_price).map(&:object).inspect