2017-04-10 57 views
1

我需要find_by_sql返回一个ActiveRecord :: Relation对象。这似乎是不可能的。然后我想用纯ruby写我的查询。find_by_sql返回activeRecords关系

我有一个关系的表本身:

class Alarma < ApplicationRecord 
    **belongs_to :root, class_name: "Alarma", foreign_key: "relacionada_id", optional: true 
    has_many :children, class_name: "Alarma" , foreign_key: "relacionada_id"** 

这是表:

create_table "alarmas", force: :cascade do |t| 
    t.string "sysname" 
    t.string "component" 
    t.string "details" 
    t.integer "estado_id" 
    t.integer "relacionada_id" 
    t.datetime "created_at",  null: false 
    t.datetime "updated_at",  null: false 
    t.index ["estado_id"], name: "index_alarmas_on_estado_id", using: :btree 
    t.index ["severity_id"], name: "index_alarmas_on_severity_id", using: :btree 
    end 

这是我在SQL查询:

Alarma.find_by_sql("SELECT a1.* FROM alarmas a1 LEFT OUTER JOIN alarmas a2 ON a1.relacionada_id=a2.id 
WHERE a1.estado_id IN (1,2) OR a2.estado_id IN (1,2)") 

的Alarma可能是根,然后它有孩子警报,或者它可能处于状态:estado_id = 2这意味着它是一个孩子,并且有根报警,(这个报警是relacionada_id)。

例子:

根报警,relacionada_id = NULL,ID = 99 儿童报警,relacionada_id = 99,ID = 112

我需要的是报警的列表,状态estado_id = 1或2,和他的根在状态estado id 1或2(和他的状态)

的警报我可以得到它与我自己的sql查询使用find_by_sql但它返回一个数组,并且我需要一个ActiveRecord: :关系对象,因为我需要继续处理结果(因为我使用分页宝石和订单和页面方法don'与阵列T工作)

+0

find_by_sql中的代码解决了我的问题。问题是我需要继续处理结果(使用gem分页和排序),并且这个结果应该是一个ActiveRecord关系。我没有Sql的经验,在rails中使用复杂查询时,我可以在纯SQL中使用左外连接来获得它,我不知道如何以rails方式编写它。 – Bri4n

+0

@ Bri4n“Alaram”,“Estado”和“Relacionada”之间的关联是什么? – Kavincat

+0

我编辑我的问题是更清楚一点。谢谢@Kavincat – Bri4n

回答

3

Converting an array of objects to ActiveRecord::Relation

的技巧是,你把原始的SQL语句的结果的ID,并进行使用where所以它返回一个ActiveRecord::Relation第二查询。

as_array = Alarma.find_by_sql("SELECT a1.* FROM alarmas a1 LEFT OUTER JOIN alarmas a2 ON a1.relacionada_id=a2.id WHERE a1.estado_id IN (1,2) OR a2.estado_id IN (1,2)") 

as_relation = Alarma.where(id: as_array.map(&:id)) 
+0

这就要求你将所有的ID加载到内存中,效率相当低 – teacher