web-dev-qa-db-ja.com

Rails:ループの反復ごとにテーブルからデータを取得する

ループ(@dataset内のアイテム)があり、各反復で、別のテーブルから異なるデータを取得し、ビューに出力されるいくつかの操作を行います。ループで使用されるデータセットからこのデータを取得できません。

MVCに従ってこれを行うにはどうすればよいですか?ビュー内のコードをループに入れることはできますが、恐ろしいことだと思います。

これを行うにはヘルパーを使用し、ビューから関数を呼び出す必要がありますか?

前もって感謝します、

-ARemesal

28
ARemesal

1つのテーブルがあり、別のテーブルからデータを取得する場合、通常これはhas_many関係。たとえば、@peoplePersonモデル)、および各個人has_manyアドレス(Addressモデル)。そのような場合に最も良いことはこれです

# Controller
@people = Person.find(:all, :include => :addresses)
...

# View
@people.each do |p|
  p.addresses.each do |address|
    ...

データが通常のデータベーステーブルだけではない場合(Webサービスなどから取得する可能性があります)、事前にコントローラーにすべてのデータを構築し、それをビューに渡すことをお勧めします。このようなもの

# Controller
@people = Person.find(:all)
@people.each do |p|
  # attach loaded data to the person object in controller
  p.addresses = Address.load_from_somewhere_by_name(p.name)
...

このように、ビューコードは次のようにクリーンなままです。

# View
@people.each do |p|
  p.addresses.each do |address|
    ...
46
Orion Edwards

私なら、データセットをカプセル化し、データセットエントリの処理に関連するすべてのロジックを含む別のクラスを作成します。このクラスは反復可能です(それぞれに対応)。次に、このクラスのインスタンスをビューに渡し、そこでそのメソッドのみを使用します。

1
Adam Byrtek
Person(id, name, other fields...)
Event(id, title, ...)
Date(id, date, time, event_id, ...)
Disponibility(id, percent, date_id, person_id, ...)

もちろん、すべての関係はモデルで定義されます。

イベントのすべての日付を表示するビューがありますが、簡単です。しかし、日付ごとに、その日付で利用可能なすべての人々のデータを印刷する必要があります。私の見解では、MVCデザインパターンを忘れて、次のようなコードを書くことができます。

<% for date in @Dates 
  available = Disponibility.find_by_date_id(date.id)
  for item in available
    guy = Person.find_by_id(item.person_id)
%>

レンダリング日と利用可能な人...

ビューでこれを避けたいです。 Orion Edwardsの答えは必要なものに最も近いと思いますが、その例では、住所はPersonテーブルの空のフィールドですか?または、Personクラスに新しい属性を追加するにはどうすればよいですか?

ただし、これを行うためのSQLトリックはありませんか?

1
Nadeem Yasin

モデル(テーブル)間のデータと関係の詳細がないと、問題の最善の解決策を伝えるのは非常に困難です。一般的な考え方は次のとおりです。ビューを愚かに保ちます。コントローラアクション内でビューをレンダリングするために必要なすべてのデータを取得します。同じアクション内ですべての変更と計算を行います。次に、このデータをビューで使用します。

ところで、N + 1の問題について話している場合は、ActiveRecordパラメーター「include」と「joins」について詳しく読んでください。

1
IDBD
  • @datasetアイテムのすべてのロジックをコントローラーアクション内に保持する
  • 必要な他のモデルオブジェクトとの相互作用のためにモデルのメソッドを利用します
  • ビューの@datasetのみを残して、パーシャルでレンダリングできます。

それについての答えをさらに得るには、状況をさらに説明する必要があります。どのような操作や他のモデルとやり取りする必要がありますか?モデルの関連付けを投稿する場合、私たちは本当にあなたを追い払うことができると確信しています。

幸運を!

0
mwilliams