多个 has_many 实例,不同类别,相同形式

several has_many through instances, of diffrent categories, in the same form

我一直在研究一个简单的场景:用户可以加入每种类型的一组。我正在尝试构建一个显示所有类型的表单,并在每种类型的名称下显示 - 该类型的所选组,或者如果用户不是该类型的成员,则选择 select 框来选择该类型的组一.

到目前为止,我只能为每种类型想出一个单独的表格 - 相当不方便。几天来我一直在努力解决这个问题。我通过表格找到了实例的唯一性 collection_select 和 has_many 的解释,但我找不到组合解决方案的方法。

型号:

class User < ActiveRecord::Base
  has_many :memberships
  has_many : groups, through: :memberships
end

class Group < ActiveRecord::Base
  has_many : memberships
  has_many :users, through: :memberships
  belongs_to :group_type
end

class Membership < ActiveRecord::Base
  belongs_to :user
  belongs_to :group
  validates :user_id, uniqueness: { scope: [:group_id, :group_type] }
end

class GroupType < ActiveRecord::Base
  has_many :groups
end

查看:

<% @types = GroupTypes.all %>
<% @types.each do |type| %>
  <%= '#{@type.name}' %>
  <% @active_group = user.groups.where(type :type) %>
  <% if @active_group.exist? %>
      <%= '#{@active_group}' %>
       <%= link_to 'Leave', [group.user], method: :delete,  data: { confirm: 'Are you sure?' } %>
  <% else %>
      <%= form_for (Membership.new) do |f| %>
         <%= f.hidden_field :user_id, value: @user.id %>
         <%=  f.collection_select :group_id, Groups.all.where(type :type), :id, :name
         <%= f.submit %>
      <%end>  
    <%end> 
 <%end>        

控制器:

Class MembershipController < ApplicationController
def create
    @user = User.find(params[:user_id])
    @group = Group.find(params[:group_id])
    @membership = user.membership.create(group :@group )
    @user. memberships << membership 
    redirect_to user_register_path
  end

  def destroy
    @user = User.find(params[:user_id])
    @user.groups.find_by(group : params[:group_id]).delete
    redirect_to user_register_path
  end

  private
    def membership_params
      params.require(:membership).permit(:user_id, :group_id)
    end
end

不确定它是否正常工作,但正如我写的那样,我对为每个分类的表单的想法不满意。想知道是否有人可以就该基本问题的解决方案提出建议。

谢谢!

不是一个完整的答案,但我想发帖

整个想法是 DRYING 你的代码你可以很容易地看到你的问题的解决方案

1) DROP the TypeGroup model

class Group < ActiveRecord::Base
  has_many : memberships
  has_many :users, through: :memberships
  has_many :types, class_name: "Group",
                      foreign_key: "type_id"
  belongs_to :type, class_name: "Group"
end

迁移

class CreateTypes < ActiveRecord::Migration[5.0]
  def change
    create_table :groups do |t|
      t.references :type, index: true
      t.timestamps
    end
  end
end

2) 你的控制器#new

def new
    @active_groups = current_user.groups.map{ |group| group.types} 
    @types = Type.all
end 

3) 使用表单助手

def user_group?
   type.group.user == current_user
end

4) 擦干你的表格

<% @types.each do |type| %>
  <%= '#{@type.name}' %>
  <% if  user_group? %>
      // show your form
  <%end>  
  // etc etc
<%end> 

我也从不使用这种显示子表单并使用它来查询父表单的架构,但通常我总是从父表单开始构建一个 nested form