2017-07-13 30 views
0

これはRails言語が欠けているのか、スタックオーバーフローで間違ったことをすべて探しているのか分かりませんが、配列の各レコードに属性を追加する方法がわかりません。ここで配列内の各レコード/オブジェクトに属性/プロパティを追加する方法は? Rails

は私がやろうとしているものの例である:

@news_stories.each do |individual_news_story| 
    @user_for_record = User.where(:id => individual_news_story[:user_id]).pluck('name', 'profile_image_url'); 
    individual_news_story.attributes(:author_name) = @user_for_record[0][0] 
    individual_news_story.attributes(:author_avatar) = @user_for_record[0][1] 
end 

任意のアイデア?

答えて

1

NewsStoryモデル(またはその名前が何であるか)がbelongs_toの関係をUserに設定している場合は、これを行う必要はありません。あなたは直接関連しUserの属性にアクセスすることができます

@news_stories.each do |news_story| 
    news_story.user.name # gives you the name of the associated user 
    news_story.user.profile_image_url # same for the avatar 
end 

N+1 queryを回避するには、NewsStoryクエリでincludesを使用することにより、一度にすべてのニュース記事に関連付けられているユーザレコードをプリロードすることができます

NewsStory.includes(:user)... # rest of the query 

@user_for_recordクエリが不要— Railsが重労働を起こすことがあります。また、すべての単一ノードに対して個別のpluckクエリを発行しないため、パフォーマンスが向上することもありますコレクションのwsストーリー。

あなたは関係なく、そこにそれらの余分な属性を持っている必要がある場合:

あなたのNewsStoryクエリで追加の属性としてそれらを選択することができます。

NewsStory. 
    includes(:user). 
    joins(:user). 
    select([ 
    NewsStory.arel_table[Arel.star], 
    User.arel_table[:name].as("author_name"), 
    User.arel_table[:profile_image_url].as("author_avatar"), 
    ]). 
    where(...) # rest of the query 
+0

ありがとうございます@マテ、私は今ハードクエリを実行するのではなく、アサーションの利点を使用しています。しかし、私はまだレコード/オブジェクトに追加の属性/プロパティとしてこれらの値を割り当てることができません。私は元の質問でこれを述べたはずですが、私が追加しようとしているこれらの特性はモデルに固有のものではありません。私は単にそれらを追加して、望ましいAPI応答を形成しています。これが可能かどうか、またはそれらが最初からモデルの属性でなければならないかどうかは分かりますか? – CFitz

+0

私の答えを更新しました。 APIレスポンスの表示方法を制御したいのであれば、ActiveRecordクエリを変換するのではなく、シリアライザを使用する必要があります。 –

+0

@Mátéありがとうございました。更新された回答とシリアライザの推奨事項の両方に本当に感謝しています。これを調べるつもりです。 – CFitz

0

あなたがキャッシュしようとしているように見えますNewsStoryモデル上のユーザ名とアバター、その場合には、何をしたいことはこれです:

@news_stories.each do |individual_news_story| 
    user_for_record = User.find(individual_news_story.user_id) 

    individual_news_story.author_name = user_for_record.name 
    individual_news_story.author_avatar = user_for_record.profile_image_url 
end 

2つの音符。

  1. 私はfind代わりのwhere使用しました。 findは、その主キー(id)によって識別される単一のレコードを返します。 whereはレコードの配列を返します。これを行うためのより効率的な方法は、間違いなく - eager-loadingですが、始めたばかりなので、基本的なことを学ぶ前に、高度なものを掘り下げてより効果的なものにすることが重要です。

  2. 私は、 pluckコールの解消を得ている
  3. ので、ここでもう一度、あなただけの学習しているとpluckは、大量のデータで作業しているときのパフォーマンスの最適化に有用であり、それはだ場合、あなたがやっていることactiverecordにはbatch apiがあります。

  4. @user_for_recorduser_for_recordに変更しました。 @は、ルビのインスタンス変数を示します。インスタンス変数は、クラスのインスタンス内の任意のインスタンスメソッドから共有およびアクセスできます。この場合、必要なのはローカル変数だけです。

関連する問題