1

I'm fairly new to Rails, and I was confused as to how I could pass local variables outside the if...else statement. It looks like creating a method in the helper file is the conventional way to do this, but I wasn't sure how to do this.

So I'm trying to get the Author of a Mission. If the author of a mission doesn't exist, I want to use the author of its parent Syllabus (missions belong to syllabus). And then I want to print out the username of that author. I was able to do this when I was dealing with only one mission, like:

//controller
@mission = Mission.first
if !@mission.author.blank?
  @author = @mission.author
else
  @author = @mission.syllabus.author
end

//view
<%= @author.username %> 

but I wasn't sure how to do this when I was dealing with a foreach loop:

//controller
@mission = Mission.all

//view 
<% @mission.each do |mission| %>
..(where do I put the logic of finding author? I can't put it in my controller anymore and it won't pass the @author variable outside the if else statement if I put the logic here in the view)..
<%= @author.username %>
<% end %>

My futile attempt was to create a helper:

def author_getter(mission_id)
  @mission = Mission.find(params[:mission_id])
  if !@mission.author.blank? 
    @author = @mission.author 
    return @author
  else
    @author = @mission.syllabus.author  
    return @author
  end 
end

and putting the below inside the loop

<%= author_getter(mission) %>

However, this didn't work. What would be the best way to pass on a variable outside the if...else statement?

4

2 に答える 2

3

ヘルパー メソッドは少し混乱しています。ヘルパーは をいじってはいけませんparams。呼び出された引数を使用して処理を行う必要があります。を渡していますmission_idが、使用していませんmission。ID が要求されているよりもパラメーター名が示している場合は、(明らかに) オブジェクトを使用して呼び出しています。また、ヘルパーでインスタンス変数をいじる必要はありません。単純な古い変数で十分です。

インターフェイスを調整して Mission オブジェクトを要求し、そのオブジェクトを使用します。

def author_of(mission)
  mission.author.present?? mission.author : mission.syllabus.author
end

または、mission.authorあるべきnilかそこにあるため、次の偽を利用できますnil

def author_of(mission)
  mission.author || mission.syllabus.author
end

次に、ERB で:

<!-- Note that you should use the plural @missions for a collection, you'll have to fix your controller as well. -->
<% @missions.each do |mission| %>
    <%= author_of(mission).username %>
<% end %>

もちろん、ヘルパーを単純化して修正したら、小さすぎて気にする価値がないと判断するかもしれません。もしそうなら、ヘルパーを捨ててERBですべてを行うことができます:

<% @mission.each do |mission| %>
    <%= (mission.author || mission.syllabus.author).username %>
<% end %>

ただし、このロジックは間違った場所にあると思います。これは、すべて (他のモデル、JSON ビルダーなど) がそれを利用できるように、Mission 自体の内部にある必要があります。したがって、次のような方法は理にかなっています。

class Mission
  def real_author
    author || syllabus.author
  end
end

次に、ERB で次のように言うことができます。

<% @missions.each do |mission| %>
    <%= mission.real_author.username %>
<% end %>
于 2012-05-11T01:01:17.407 に答える
0

私があなたの質問を誤解していない限り、検索を使用せずにループでこれを行うことができます。

//view 
<% @mission.each do |mission| %>
   <%= mission.author.username %>
<% end %>

すべての Mission オブジェクトを繰り返し処理していることを思い出してください。ミッション オブジェクトを取得したら、通常どおり作成者にアクセスできます。

于 2012-05-11T00:47:42.603 に答える