4

Ruby のすばらしさにより、任意のオブジェクトをキーとして使用できます。

document = Document.find 1
o = Hash.new
o[1] = true
o[:coool] = 'it is'
o[document] = true
# an it works

o[document]
#=> true

しかし、それが可能だからといって、それが良い習慣であるとは限りません

ただし、コントローラーで同様のものを設定する必要がある状況があるため、ビューでループすることができます

#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 }

なぜこのようにしたいのかというと、自分の観点から呼び出したくない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 }

だから私の最初の質問は:このような状況で ActiveRecord オブジェクトをハッシュキーとして使用しても大丈夫ですか?

これがうまくいかない可能性があるいくつかのシナリオ (セッション、モデルでオブジェクトが変更されたときなど) を想像できますが、これはビューでレンダリングするためだけのものです。

別 !

これはそれを行う1つの方法であり、もう1つはこのようなものかもしれません

#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 }    

...さらにハードコアです。hash[ARobject] = :somethingただし、何らかの理由で大きなメモリクラスターが作成される場合は回避策です

質問 2:このようにするのは良い考えですか?


完全にするために、別の選択肢もあり、それは

# ...
@user_with_thing[ [thing.user.id, thing.user.type] ] << thing_id
# ...

基本的に配列オブジェクトがキーになります

@user_with_thing[ [1, 'Admin'] ] 
#=> [1,2,3]
4

1 に答える 1

4

ハッシュを使用することは、状況を整理するための良い方法だと思います。ただし、ユーザーを使用したり、オブジェクトをハッシュキーとして大きくしたりすることはお勧めしません。これは、単にハッシュが読み取れなくなり、キーとして使用できるオブジェクト ID を持つ唯一のオブジェクトであるためです。

o = Object.new
h = { o => 'something' }
h[Object.new] #=> nil

あなたの状況では、単に反復する必要があるため、これは問題にならないかもしれません。しかし、そのハッシュで何か他のことをしたい場合や、同じアクティブ レコード データの異なるインスタンスがある場合 (実際に注意を払っていない限り、これは Rails アプリケーションでは非常に一般的です)ときにロードされます)。それに加えて、単純なオブジェクト (文字列、シンボル) をハッシュ キーとして使用して、コードを読みやすく保守しやすくするという、広く使用されている規則に従うのは良いことだと思います。

おそらく、次のように 2 次元のハッシュを保持するのが最善でしょう。

@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

@users_with_things次に、次のようにビューで反復できます。

@users_with_things.each do |user_id, values|
  # values[:user] is the user, values[:things] the array of things
于 2013-01-11T14:35:06.373 に答える