几个has_many通过实例,不同的类别,以相同的形式

时间:2018-03-11 14:24:42

标签: ruby-on-rails has-many-through collection-select

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

到目前为止,我只能为每种类型提出一个单独的形式 - 相当不方便。我好几天都想解决这个问题。我通过表单找到了实例的uniqness,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>        

controlller:

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

不确定它是否正常工作,但正如我所写,我对每个导管的形式的想法不满意。我想知道是否有人可以为这个基本问题提供解决方案。

谢谢!

1 个答案:

答案 0 :(得分:1)

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

整个想法是干燥您的代码,您可以轻松地找到问题的解决方案

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