2014-06-30 30 views
0

我从Active Record采集中发现了一个奇怪的行为。检索多个记录,使用连接和采摘的列

我查询

Friend.joins('INNER JOIN users ON friends.friend_id = users.id').where("user_id=? AND (status=? or status=?)", 4,"true","").pluck("users.first_name, users.last_name") 

它与各界朋友与用户,并得到用户的姓氏和名字

生成的SQL命令是

SELECT users.first_name, users.last_name FROM "friends" INNER JOIN users ON friends.friend_id = users.id WHERE (user_id=4 AND (status='true' or status='')) 

如果我上面的命令运行在SQLite浏览器工具

我得到的回复如

first_name last_name 

    user4  y 
    user5  y 

但在命令行与勇气

["y", "y"] 

和命令行用的find_by_sql

[#<Friend >, #<Friend >] 

什么是错在我的代码,或者是问题的勇气和的find_by_sql

我该如何解决这个问题?

在此先感谢

回答

0

配置/初始化/ pluck_all.rb

module ActiveRecord 
class Relation 
    def pluck_all(*args) 
    args.map! do |column_name| 
    if column_name.is_a?(Symbol) && column_names.include?(column_name.to_s) 
     "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(column_name)}" 
    else 
     column_name.to_s 
    end 
    end 

    relation = clone 
    relation.select_values = args 
    klass.connection.select_all(relation.arel).map! do |attributes| 
    initialized_attributes = klass.initialize_attributes(attributes) 
    attributes.each do |key, attribute| 
     attributes[key] = klass.type_cast_attribute(key, initialized_attributes) 
    end 
    end 
end 

末 结束

Friend.joins('INNER JOIN users ON friends.friend_id = users.id').where("user_id=? AND (status=? or status=?)", 4,"true","").pluck_all("users.first_name","users.last_name") 

解决我的问题,这纯粹是一个勇气的问题。

感谢一个great tutorial

0

如果你使用的轨道4,你可以做

而不是

.pluck("users.first_name, users.last_name") 

尝试

.pluck("users.first_name", "users.last_name") 

在轨道3,你会想使用select选择这些特定字段

.select("users.first_name", "users.last_name") 
+0

它提供了一个错误错误的参数数目(2表示1) – santosh

+0

您使用的是哪种版本的导轨?对不起,忘了采用rails进行修改4. Rails 3只接受1个参数。 –

+0

我只使用rails3 – santosh

0

在制造轨道3的方法,其行为一样的轨道4拔毛具有多个列的条款。 这会输出一个类似的数组(而不是散列键值集合)。

module ActiveRecord 
    class Relation 
    def pluck_all(*args) 
     args.map! do |column_name| 
     if column_name.is_a?(Symbol) && column_names.include?(column_name.to_s) 
      "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(column_name)}" 
     else 
      column_name.to_s 
     end 
     end 

     relation = clone 
     relation.select_values = args 
     klass.connection.select_all(relation.arel).map! do |attributes| 
     initialized_attributes = klass.initialize_attributes(attributes) 
     attributes.map do |key, attribute| 
      klass.type_cast_attribute(key, initialized_attributes) 
     end 
     end 
    end 
    end 
end 

站在巨人的肩膀上,所有(@santosh)

0

article @santosh共享是伟大的,直到我准备从Rails的3.2升级到Rails 4。

这是一个gem pluck_all来解决这个问题,使得pluck_all方法不仅支持Rails 3,而且支持Rails 4和Rails 5.希望这可以帮助那些将要升级rails版本的人。