多个 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 你的代码你可以很容易地看到你的问题的解决方案
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
我一直在研究一个简单的场景:用户可以加入每种类型的一组。我正在尝试构建一个显示所有类型的表单,并在每种类型的名称下显示 - 该类型的所选组,或者如果用户不是该类型的成员,则选择 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 你的代码你可以很容易地看到你的问题的解决方案
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