Ruby on rails 使用ActiveRecord获取列名称
有没有办法通过ActiveRecord获得实际的列名称 当我调用find_by_sql或select_all with a join时,如果有同名的列,则会覆盖第一列:Ruby on rails 使用ActiveRecord获取列名称,ruby-on-rails,activerecord,Ruby On Rails,Activerecord,有没有办法通过ActiveRecord获得实际的列名称 当我调用find_by_sql或select_all with a join时,如果有同名的列,则会覆盖第一列: select locations.*, s3_images.* from locations left join s3_images on s3_images.imageable_id = locations.id and s3_images.imageable_type = 'Location' limit 1 在上面的示例
select locations.*, s3_images.* from locations left join s3_images on s3_images.imageable_id = locations.id and s3_images.imageable_type = 'Location' limit 1
在上面的示例中,我得到以下结果:
#<Location id: 22, name: ...
>
我需要获取上面行的字段名。
这篇文章接近我想要的,但看起来过时了(fetch_字段似乎不再存在)
ActiveRecord连接方法创建多个对象。我正在尝试实现与“includes”返回相同的结果,但使用左连接
我试图返回大量结果(有时是整个表),这就是为什么Include不适合我的需要。Active Record提供了一个
#column_names
方法,该方法返回一个列名数组
用法示例:
User.column\u name
这正是active record的inspect方法的工作方式:它只列出模型表中的列。但这些属性仍然存在
record.blah
将返回blah属性,即使它来自另一个表。你也可以使用
record.attributes
获取包含所有属性的哈希
但是,如果有多个名称相同的列(例如,两个表都有一个id列),则active record只会将内容合并在一起,而忽略表名。您必须为列名添加别名以使其唯一。好的,我一直想做一些更高效的事情 请注意,对于非常少的结果,包括工作刚刚好。当您有很多列想要加入时,下面的代码工作得更好 为了使代码更容易理解,我首先制定了一个简单的版本并对其进行了扩展 第一种方法:
# takes a main array of ActiveRecord::Base objects
# converts it into a hash with the key being that object's id method call
# loop through the second array (arr)
# and call lamb (a lambda { |hash, itm| ) for each item in it. Gets called on the main
# hash and each itm in the second array
# i.e: You have Users who have multiple Pets
# You can call merge(User.all, Pet.all, lambda { |hash, pet| hash[pet.owner_id].pets << pet }
def merge(mainarray, arr, lamb)
hash = {}
mainarray.each do |i|
hash[i.id] = i.dup
end
arr.each do |i|
lamb.call(i, hash)
end
return hash.values
end
我这样称呼它:
lambmerge = lambda do |lhash, rhash, lid, rid|
lhash[lid].keywords << rhash[rid]
end
Location.merge_through!(Location.all, Keyword.all, LocationsKeyword.all, lambmerge)
以下是我如何使用代码:
def merge_multi_test()
merge_multi!(Location.all,
[
# each one location has many s3_images (one to many)
{ :value => S3Image.all,
:proc => lambda do |img, hash|
if (img.imageable_type == 'Location')
hash[img.imageable_id].s3_images << img
end
end
},
# each location has many LocationsKeywords. Keywords is the right table and LocationsKeyword is the middletable.
# (many to many)
{ :value => Keyword.all,
:middletable => LocationsKeyword.all,
:proc => lambda do |lhash, rhash, lid, rid|
lhash[lid].keywords << rhash[rid]
end
}
])
end
def merge_multi_test()
合并多个!(全部,
[
#每个位置都有许多s3_图像(一对多)
{:value=>S3Image.all,
:proc=>lambda do | img,散列|
如果(img.imageable_type=='Location')
哈希[img.imageable\u id].s3\u images关键字.all,
:middletable=>LocationsKeyword.all,
:proc=>lambda do | lhash,rhash,lid,rid|
lhash[lid].关键词两个选项
Model.column_names
或
范例
名为Rabbit的模特在facebook上有“姓名”、“年龄”等栏目
Rabbit.column_names
Rabbit.columns.map(&:name)
返回
["id", "name", "age", "on_facebook", "created_at", "updated_at"]
您可以使用:model.columns.map(&:name)获取ActiveRecord模型的所有列,但我不确定这是否是您想要的。当我进行联接时,我不知道哪些值属于哪些模型。这就是我想要列的名称的原因。谢谢您的回答。我尝试了别名,但在AR中没有得到任何不同。它始终是相同的混合结果。AR希望有任何特定的别名吗?每个列名称都有eds是唯一的,例如,选择table1.*、table2.id a s t2_id、table2.name as t2_name等。AR对此不会做任何巧妙的处理,但它会停止所有冲突这意味着我必须为每个重复列别名…非常繁琐:-(对于将来来到这里的任何人来说,此方法都是不推荐的,谢谢分享,@pahnin;如果您(或其他任何人)可以推荐其他方法,那就太好了。Column_names()仍然适用于ActiveRecord类,它刚刚被移到了另一个模块中。ModelName.columns.map(&:name)
截至2015年6月仍能正常工作。
Model.column_names
Model.columns.map(&:name)
Rabbit.column_names
Rabbit.columns.map(&:name)
["id", "name", "age", "on_facebook", "created_at", "updated_at"]