如何从关联模型(Rails)中提取信息

时间:2014-05-04 07:49:41

标签: ruby-on-rails ruby activerecord ransack

我正在使用Ransack gem进行搜索。

控制器代码(对于ItemsController)

@q = Item.search(params[:q])
@search_results = @q.result

运行搜索后,@search_results包含多个Items(第1项,第2项,第3项,......)。每个项目都是哈希值:

Item = { "id" => "12", "name" => "shovel", "user_id" => "2", "type" => "A" }

在这种情况下,对于每个Item哈希,我想添加一个额外的键值对,将user_id转换为与User模型的该实例关联的名称(即, User has_many :ItemsItem belongs_to :Users

我尝试使用相同的控制器代码部分

@search_results.each do |item|
    item[:user_name] = User.find_by_id(item.user_id).name
end

但是我收到一个错误,我无法写入项目。我怀疑Ransack与它有关,因为如果我只是打印@search_results,而不是获取实际的Item数据,我得到#<ActiveRecord::Relation::ActiveRecord_Relation_Item:0x000001025e6c78>

非常感谢!

顺便说一句,如果有更简单的方法,我想用user_name添加另一个键/值对的原因是因为最终输出是一个JSON,它被另一部分代码库拾取,我们不知道我想运行两个单独的数据库查询。

1 个答案:

答案 0 :(得分:2)

首先,你收到一个ruby对象,我认为你可以在模型中创建一组属性。为什么不尝试使用item模型中的getter为您设置:

#app/models/item.rb
Class Item < ActiveRecord::Base
    belongs_to :user #-> needs to be singular
    attr_accessor :user_name

    def user_name
       self.user.name
    end
end

这意味着您无需在控制器中附加user_name属性,而是每个Item对象都会自动拥有user_name属性

这样做的重构也是使用Item模型中的delegate method

Class Item < ActiveRecord::Base
    belongs_to :user
    delegate :name, to: :user, prefix: true #-> allows you to call @item.user_name
end