0

私のアプリには、 Student と Parent の 2 つのモデルがありstudent belongs_to parentます。

親には属性がnameあり、contact_no

私がやりたいことは、ある条件に基づいて

@h=Hash.new
@students = Student.find(:condition)
@students.each do |student| 
  @h[@student.parent.contact_no] = @student.parent.contact_no+','+@student.name
end

しかし、ハッシュは作成されていません。これで何が悪いのか理解できません。

1 人の生徒には問題なく機能するコードがループでは機能しない

@h=Hash["@student.parent.contact_no" = @student.parent.contact_no]
4

1 に答える 1

0

私たちが見ることができないどこかにインスタンス変数が実際に定義されていない限り...ループで符号を@student使用しないことを意図している可能性が最も高いです。@したがって、代わりに次のようにします。

@students.each do |student| 
  @h[student.parent.contact_no] = student.parent.contact_no+','+student.name
end

とはいえ、これをクリーンアップしてスピードアップするためにできることはたくさんあります。代わりにこれを行います:

@students = Student.includes(:parents).where(<condition>)  # Eager load the associated parents
@h = @students.inject({}) do |acc, student|  # Initialize the new hash and loop
  acc[student.parent.contact_no] = "#{student.parent.contact_no},#{student.name}"  # String interpolation is faster than concatenation
  acc  # Return the accumulator
end

ここでinject( と呼ばれることもありreduceます) は、新しいハッシュを初期化し、最後に構築されたハッシュを返します。次に、parentsアソシエーションの熱心な読み込みを使用したため、ループの各反復でデータベース ルックアップを実行しません。最後に、文字列の補間 ( "#{}") は、文字列の連結 ( ) よりも高速です"" + ""

于 2013-09-21T12:54:52.807 に答える