开发者

Accessing Attributes in a Many-to-Many

开发者 https://www.devze.com 2023-02-04 08:36 出处:网络
I have a rails app and I\'d like to be able to do something like task.labels.first.label_name to get the label name of a task.However, I get an undefined method label_name.I did a t = Task.first; t.l

I have a rails app and I'd like to be able to do something like task.labels.first.label_name to get the label name of a task. However, I get an undefined method label_name. I did a t = Task.first; t.labels.first.label_name in the console, and that worked so I'm not sure what's going on. Here's the models then the locations of the error:

class Categorization < ActiveRecord::Base
 belongs_to :label
 belongs_to :task
end

class Label < ActiveRecord::Base
  attr_accessible :label_name

  has_many :categorizations
  has_many :tasks, :through => :categorizations
end

class Task < ActiveRecord开发者_开发知识库::Base
  attr_accessible :task

  has_many :categorizations
  has_many :labels, :through => :categorizations
end

The error is in the index

<% for task in @tasks %>
<tr>
  <td><%= task.task %></td>
  <td><%= task.labels.first.label_name %></td>
  <td><%= link_to "Show", task %></td>
  <td><%= link_to "Edit", edit_task_path(task) %></td>
  <td><%= link_to "Destroy", task, :confirm => 'Are you sure?', :method => :delete %></td>
</tr>
<% end %>


My guess would be that one of the tasks in @tasks does not have any labels so when you call task.labels.first it returns nil and then you try to call label_name for nil which of course does not work.

The easiest solution would be to do a check like this:

<td><%= task.labels.first.label_name unless task.labels.first.nil? %></td>

Now that does not look so good in the view so you might want to place that check in your Task model instead, perhaps like this:

class Task < ActiveRecord::Base
  attr_accessible :task

  has_many :categorizations
  has_many :labels, :through => :categorizations

  def label_name
    self.labels.first.label_name unless self.labels.first.nil?
  end
end

And in the view:

<td><%= task.label_name %></td>

And another thing, just in case you would like to view all the associated labels, you could do something like this:

task.labels.map(&:label_name).join(", ")
0

精彩评论

暂无评论...
验证码 换一张
取 消