Question about Discourse's rails source code and use of exec_sql


(jon) #1

Sorry to ask a bit of a naive question but I’m trying to get similar functionality in a rails app I’m working on as something in discourse. I would like to use exec_sql and see it defined in lib/freedom_patches/active_record_base.rb where ActiveRecord::Base is being monkey-patched. The problem that I have is that

def self.exec_sql(*args)
conn = ActiveRecord::Base.connection
sql = ActiveRecord::Base.send(:sanitize_sql_array, args)
conn.execute(sql)
#conn.exec_query(sql) this changes it to getting back a hash
end

will return to me an array and NOT a hash such that if I call:

users=User.exec_sql(“select * from users”).to_a

I get:

[1,
"me@other.com"
],
 [2,
  "jtjt@some.com",
]

when I really want:

["id":1,
"name":me@other.com"
],
 ["id":2,
  "name":"jtjt@some.com",
]

It looks like changing the call to exec_query (commted out above; based on Why does Rails 3 with Mysql2 Gem ActiveRecord::Base.connection.execute(sql) return Array not Hash? - Stack Overflow ) achieves that but obviously Discourse uses the former and I’m curious how this is accomplished. Sorry if naive question but would just like to use this. thx


(Sam Saffron) #2

Have a look at SqlBuilder, discourse/sql_builder.rb at master · discourse/discourse · GitHub you can map an OpenStruct or some other real object, which gives you way cleaner semantics.