我正在尝试构建一个简单的项目管理应用程序,其中用户可以是许多项目的成员,项目可以是许多用户的成员。这种多对多关系在下面的模型中表示:
#project model
class Project < ActiveRecord::Base
has_many :memberships, dependent: :destroy
has_many :users, :through => :memberships
accepts_nested_attributes_for :memberships
end
#user model
class User < ActiveRecord::Base
has_many :memberships, dependent: :destroy
has_many :projects, :through => :memberships
accepts_nested_attributes_for :memberships
end
#membership model (join table)
class Membership < ActiveRecord::Base
belongs_to :project
belongs_to :user
end
我试图允许应用程序用户在创建项目时选择哪些注册用户是项目的成员,因此使用项目的新表单,我希望有下拉列表来选择成员用户。我目前有以下
#projects_controller.rb
def create
@user = User.find_by_id(session[:user_id])
@project = Project.new(project_params)
@project.manager_id = @user.id
respond_to do |format|
if @project.save && @project.memberships.create(:user => @user)
format.html { redirect_to projects_path, notice: "Project #{@project.name} was successfully created." }
format.json { render :show, status: :created, location: @project }
else
format.html { render :new }
format.json { render json: @project.errors, status: :unprocessable_entity }
end
end
end
def destroy
@project.destroy
respond_to do |format|
format.html { redirect_to projects_url, notice: "Project #{@project.name} was successfully deleted." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_project
@project = Project.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def project_params
params.require(:project).permit(:name, :description, memberships_attributes: [:user_id])
end
end
#index.html.erb for projects
<%= form_for(@project) do |f| %>
<% if @project.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@project.errors.count, "error") %> prohibited this project from being saved:</h2>
<ul>
<% @project.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<%= f.fields_for :memberships do |m| %>
<div class="field">
<%= m.label :user_id %><br>
<%= m.collection_select :user_id, User.all, :id, :username %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
此代码在成员资格表中添加关联,但它需要当前登录的用户,我希望它与用户从表单中选择的每个用户创建关联。 此外,我的销毁方法返回错误,我的表单collection_select没有显示。任何帮助将不胜感激。
编辑:我所做的更改:
#new.html.erb
<%= fields_for :memberships do |m| %>
<div class="field">
<%= m.label "Add Member" %><br>
<%= collection_select :users, :user_id, User.all, :id, :username %>
</div>
<% end %>
#projects_controller.rb
collection_ids = params[:users]
collection_ids.each do |user_id|
user = User.find(user_id)
@project.memberships.create(:user => user)
我收到错误"找不到所有带有'id'的用户:(user_id,3)(找到 1 个结果,但正在寻找 2)"似乎这种方式只允许用户添加一个成员如何修改表单以添加倍数?
所以我想您正在尝试为一个项目创建多个成员资格,当前用户将决定哪些用户应该是新创建项目的成员?在这种情况下
@project.memberships.create(:user => @user)
行不通,因为它只为current_user生成成员资格。因此,当您将user_ids集合传递给project_controller的创建方法时,您应该遍历这些 id 并获取这些用户,然后 为每个人创建一个新的成员资格。类似的东西
collection_ids.each do |user_id| # assuming collection_ids is an array
user = User.find(user_id)
@project.memberships.create(:user => user)
end
似乎您在collection_select中错过了对象参数,我认为应该是:
<%= m.collection_select :users, :user_id, User.all, :id, :username %>
并且,只有在将对象参数添加到表单后user_ids在选择将params[:users]
调用@project.memberships.create(:user => @user)
时,才为当前用户创建成员资格。