使用has_many编辑模型属性

时间:2014-10-23 18:07:21

标签: ruby-on-rails ruby model associations has-many-through

我成功地与我的两个模型创建了has_many through联接。总而言之,每位艺术家都可以属于多个群体,反之亦然:

# artist.rb
  has_many :memberships
  has_many :groups, through: :memberships

# membership.rb
  belongs_to :artist
  belongs_to :group

# group.rb
  has_many :memberships
  has_many :artists, through: :memberships

我想要做的是设置一个status属性,该属性将是一个布尔值,并指示艺术家是否属于该群组。因此,例如,如果艺术家离开该组,他/她将被识别为名为status过去成员布尔值(true = current_member,false = past_member)。

我不确定一些事情。第一个是决定将此属性分配给哪个模型。这三个都是吗?是2/3还是1/3?

我的第二个问题是创建一种方式,允许我在艺术家的编辑视图或他们所属的组中更改艺术家的成员身份。我希望做的是,如果从任一视图更改一个,这两个模型都会反映出这种变化。

艺术家和小组展示的观点可能会互为镜像,所以为了简洁起见,我只会列出艺术家的节目观点:

艺术家展示视图

我唯一遇到麻烦的部分是尝试列出过去的群组。我应该为此特定方案设置范围或方法吗?

<h3>Member of:</h3>
<hr>
<% @artist.groups.each do |group| %>
    <%= artist.group.name %>
    <% if artist.group.status == false %>
        <h3>Past Member of: %></h3>
        <hr>
        <!-- <% Scope or Method that filters Past Groups %> -->
    <% end %>
<% end %>

艺术家编辑视图

对于编辑视图,我似乎无法弄清楚的一件事是嵌套艺术家的每一组。我的语法可能很遥远,但只是为了让你知道我正在尝试做什么:

<%= form_for @artist do |f| %>
  <h3>Memberships</h3>
  <% @artist.groups.each do |group| %>
    <%= f.group.radio_button :status, true %>
    <%= f.group.label :status, 'Current Member', value: true %>
    <%= f.group.radio_button :status, false %>
    <%= f.group.label :status, 'Past Member', value: false %>
  <% end %>
  <br>
  <%= f.submit %>
<% end %>

群组编辑视图

我假设这看起来几乎与艺术家编辑视图完全相同但反转到了一定程度:

<%= form_for @group do |f| %>
  <h3>Memberships</h3>
  <% @group.artists.each do |artist| %>
    <div>
      <%= f.artist.radio_button :status, true %>
      <%= f.artist.label :status, 'Current Member', value: true %>
      <%= f.artist.radio_button :status, false %>
      <%= f.artist.label :status, 'Past Member', value: false %>
    </div>
  <% end %>
  <br>
  <%= f.submit %>
<% end %>

如果需要任何控制器逻辑,我全都听见了。

1 个答案:

答案 0 :(得分:1)

首先,我会将此添加到Membership,因为这是关系的真实指标

由于您正在查看单个组或艺术家,因此它将是实例方法而不是范围。类似的东西:

class Group
  has_many :memberships
  has_many :artists, through: :memberships
  def past_artists
    artists.where(memberships:{status: false})
  end
end
#might be User not sure based on your code and your question
class Artist
  has_many :memberships
  has_many :groups, through: :memberships
  def past_groups
    groups.where(memberships:{status: false})
  end
end

然后您的群组视图应该类似于

<% @group.memberships.each do |membership| %>
   <%= render '/memberships/membership_edit_form', membership: membership, obj: @group %>
<% end %>

并创建部分/memberships/_membership_edit_form.html.erb

<%= form_for membership do |f| %>
   <h5><%= obj.is_a?(Group) ? membership.artist : membership.group %></h5>
   <%= f.label :status, "Current Member?" %>
   <%= f.check_box :status %>
   <%= f.submit %>
<% end %>

请注意,提交按钮一次只会更新1个会员关系。

要立即更新多个,您应该可以执行此操作

<%= form_for @group do |f| %>
  <%= f.fields_for :memberships do |builder| %>
     <%= render '/memberships/membership_fields', f: builder, obj: @group %>
  <% end %>
  <%= f.submit %>
<% end %>

然后在/memberships/_membership_fields.html.erb中创建一个部分

<h5><%= obj.is_a?(Group) ? f.object.artist : f.object.group %></h5>
<%= f.label :status, "Current Member?" %>
<%= f.check_box :status %>

这应该允许你将它们全部传递给params,就像[:group][:memberships]之类的东西一样,但是请注意我相信正确地更新它们你将不得不迭代这个集合。