equ*_*nt8 5 ruby ruby-on-rails ruby-on-rails-3 rails-activerecord
由于 Ruby 的强大功能,可以使用任何对象作为键
document = Document.find 1
o = Hash.new
o[1] = true
o[:coool] = 'it is'
o[document] = true
# an it works
o[document]
#=> true
Run Code Online (Sandbox Code Playgroud)
但仅仅因为这是可能的并不意味着是好的做法
但是,我遇到的情况是,在我的控制器中我需要设置类似的东西,这样我就可以在视图中循环它
#controller
@users_with_things = Hash.new
Things.accessible_by(some_curent_user_logic).each do |thing|
@user_with_things[thing.user] ||= Array.new
@user_with_things[thing.user] << thing.id
end
#view
- @users_with_things.each do |user, thing_ids|
%input{type: :checkbox, name: "blank[user_#{user.id}]", value: 1, class: "select_groups", :'data-resource-ids' => "[#{thing_ids.join(',')}]", :'data-user-type' => user.type }
Run Code Online (Sandbox Code Playgroud)
我之所以想这样做是因为我不想从我的角度调用User.find_by_id (想让它干净)
#controller
@users_with_things = Hash.new
Things.accessible_by(some_curent_user_logic).each do |thing|
@user_with_things[thing.user.id] ||= Array.new
@user_with_things[thing.user.id] << thing.id
end
#view
- @users_with_things.each do |user_id, thing_ids|
- user = User.find user_id
%input{type: :checkbox, name: "blank[user_#{user.id}]", value: 1, class: "select_groups", :'data-resource-ids' => "[#{thing_ids.join(',')}]", :'data-user-type' => user.type }
Run Code Online (Sandbox Code Playgroud)
所以我的第一个问题是:在这种情况下使用 ActiveRecord 对象作为哈希键是否可以
我可以想象几种可能会出错的场景(会话、模型中的对象更改等),但这仅适用于在视图中渲染
所以这是一种方法,另一种可能是这样的
#controller
@users_with_things = Hash.new
Things.accessible_by(some_curent_user_logic).each do |thing|
@user_with_things[thing.user.object_id] ||= Array.new
@user_with_things[thing.user.object_id] << thing.id
end
#view
- @users_with_things.each do |user_object_id, thing_ids|
- user = ObjectSpace._id2ref(user_object_id) #this will find user object from object_id
%input{type: :checkbox, name: "blank[user_#{user.id}]", value: 1, class: "select_groups", :'data-resource-ids' => "[#{thing_ids.join(',')}]"", :'data-user-type' => user.type }
Run Code Online (Sandbox Code Playgroud)
...这甚至更硬核。hash[ARobject] = :something然而,如果由于某种原因会创建大的内存集群,这是可以解决的
问题2:这样做好主意吗?
为了完整,还有另一种选择,那就是
# ...
@user_with_thing[ [thing.user.id, thing.user.type] ] << thing_id
# ...
Run Code Online (Sandbox Code Playgroud)
所以基本上数组对象将是关键
@user_with_thing[ [1, 'Admin'] ]
#=> [1,2,3]
Run Code Online (Sandbox Code Playgroud)
我认为使用哈希是根据您的情况进行组织的好方法。但是,我建议不要使用用户或大对象作为哈希键,因为它会使您的哈希不可读,而且实际上只有这个唯一的对象及其对象 id 可以用作键。
o = Object.new
h = { o => 'something' }
h[Object.new] #=> nil
Run Code Online (Sandbox Code Playgroud)
在您的情况下,这可能不是问题,因为您只需要迭代它。但是,一旦你想用该哈希做其他事情,或者你有相同 Active Record 数据的不同实例(这在 Rails 应用程序中很常见,除非你真的很注意什么),这可能是一剂强心剂。时加载)。除此之外,我认为最好坚持广泛使用的约定,使用简单的对象(字符串、符号)作为哈希键,以使代码可读且可维护。
也许最好保留一个二维哈希,如下所示:
@users_with_things = Things.accessible_by(some_curent_user_logic).inject({}) do |a, thing|
user_id = thing.user.id
a[user_id] ||= { :user => thing.user, :things => [] }
a[user_id][:thing] << thing
a
end
Run Code Online (Sandbox Code Playgroud)
@users_with_things然后你可以像这样在你的视图中迭代:
@users_with_things.each do |user_id, values|
# values[:user] is the user, values[:things] the array of things
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1925 次 |
| 最近记录: |