Rails 4 has_many :through : 在父模型索引视图中显示子属性

Rails 4 has_many :through : display child attribute in parent model index view

我有三个模型,有一个 has_many :through association :

class User < ActiveRecord::Base
  has_many :administrations
  has_many :calendars, through: :administrations
end

class Calendar < ActiveRecord::Base
  has_many :administrations
  has_many :users, through: :administrations
end

class Administration < ActiveRecord::Base
  belongs_to :user
  belongs_to :calendar
end

加入管理模型具有以下属性:

id
user_id
calendar_id
role

这是我的 Calendars#Index:

def index
  @user = current_user
  @calendars = Calendar.all
end

目前,这是我的日历索引视图中的内容:

<tbody>
  <% @calendars.each do |calendar| %>
    <tr>
      <td><%= link_to calendar.name, user_calendar_path(@user.id, calendar.id) %></td>
      <td><%= link_to 'Destroy', user_calendar_path(@user, calendar), method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
  <% end %>
</tbody>

现在,在每个日历名称之后,仍然在日历索引视图中,我想显示当前用户对该日历的角色。

为此,我需要从 administrations 联接 table 获取信息,其中 user_id = current_user.id(或 @user.id)和 calendar_id = calendar.id

我尝试了不同的解决方案,但将 运行 保留为 NoMethodErrors 和 NameErrors。

——————————

更新:

以下是我尝试过的不同解决方案。

解决方案 1

在日历索引视图中添加 <td><%= calendar.administration.role %></td>

返回:

NoMethodError in Calendars#index
undefined method `administration' for #<Calendar:0x007f88fb88a050>

解决方案 2

在日历索引视图中添加 <td><%= calendar.administrations.role %></td>

返回:

NoMethodError in Calendars#index
undefined method `role' for #<ActiveRecord::Associations::CollectionProxy []>

解决方案 3

在日历索引视图中添加 <td><%= calendar.role %></td>

返回:

NoMethodError in Calendars#index
undefined method `role' for #<Calendar:0x007f88faf66a78>

——————————

我怎样才能完成这项工作?

您可以像这样直接从您的视图中直接从 Administration 模型获取 role,因为您已经可以在您的视图中访问 @usercalendar

Administration.where(user_id: @user.id, calendar_id: calendar.id).first.try(:role)

一个日历有很多管理,每个用户一个。您需要找到与您的特定用户关联的那个。发现可以这样做 calendar.administrations.where(user_id: @user.id) 要么 calendar.administrations.select{|administration| administration.user_id = @user.id}

现在,这些 return 是一个列表,而不是一个单独的项目,因此您需要获取第一个: calendar.administrations.where(user_id: @user.id).first 您现在拥有给定用户的第一个管理对象。然后你可以申请这个角色。

试试这个作为解决方案。 <%= calendar.administrations.where(user_id: @user.id).first.role %>