我必须使用activerecord模型
Model1 and Model2
Model1
有name
和info
个字段
Model2
有state
和price
我想创建一个对象数组,它们将是model1 + model2的联合体。
每个sum_model
对象都应具有name, info, state, price
个属性。
应该是Model1.all
和Model2.all
的总和。例如:
如果Model1.all
返回一条name="name" and info ="zz"
Model2.all
会返回state='state' and price=14
model_sum
应该是一个包含2个对象的数组:
[{name:'name', info: 'zz', state: '', price: ''}, {name:'', info: '', state: 'state', price: 14}]
我该怎么做?
答案 0 :(得分:0)
您应该能够通过在Model1
和Model2
之间构建cartesian product(将一个表的每个记录与另一个表的每个表结合起来)来实现您想要实现的目标获取结果模型的属性(其中包含Model1
和Model2
的属性:
Model1
.joins("CROSS JOIN #{Model2.table_name}")
.select("#{Model1.table_name}.*, #{Model2.table_name}.*")
.map(&:attributes)
为了做到这一点,两个模型之间不需要存在关联。
重新阅读问题并注意到我错过了
之后编辑您首先必须调整两个模型的选择,以使UNION
匹配列。幸运的是,可以在AR语句中添加任意选择,例如
m1 = Model1.select(:name, :info, "'' as state", "'' as price")
m2 = Model2.select(:state, :price, "'' as name", "'' as info")
然后你将不得不手工制作UNION,因为AR不支持。这是由Arel,但我大多数时候怀疑Arel是值得的斗争:
union = Model1.connection.unprepared_statement do
"((#{m1.to_sql}) UNION (#{m2.to_sql})) AS unioned"
end
然后你可以使用union作为from值来解除select,然后调用每个返回条目的attributes
方法来实现你指定的结果:
Model1
.select('*')
.from(union)
.map(&:attributes)