我的项目可以有一个projectOwner
和多个projectMembers
。创建项目后,我希望能够将用户添加到此项目中。
现在我的问题是我必须在创建新user_id
时输入project_id
和projectMember
。该表单需要user_id
和project_id
,因此我如何更改它以便email
,然后找到与其相关的user_id
。
查看:
<%= form_for([@project, @project.project_members.build]) do |f| %>
<p>
<%= f.label :project_id %><br>
<%= f.text_field :project_id %>
</p>
<p>
<%= f.label :user_id %><br>
<%= f.text_field :user_id %>
</p>
<p>
<%= f.submit :Add, class: 'btn btn-info' %>
</p>
<% end %>
控制器:
def create
@project_member = ProjectMember.new(member_params)
@project_member.save
end
private
def member_params
params.require(:project_member).permit(:user_id, :project_id)
end
模型关系:
class User < ApplicationRecord
has_many :roles
has_many :projects, through: :roles
end
class Role < ApplicationRecord
belongs_to :user
belongs_to :project
end
class ProjectOwner < Role
end
class ProjectMember < Role
end
class Project < ApplicationRecord
has_many :project_members
has_many :members, class_name: "User", through: :project_members
has_one :project_owner
has_many :owners, class_name: "User", through: :project_owner
end
现在我的路线看起来像这样,但我觉得这不是正确的做法:
devise_for :users
resources :users do
resources :projects
end
resources :projects do
resources :project_members
end
答案 0 :(得分:1)
表单需要user_id和project_id,所以我该如何更改 这样它就会收到一封电子邮件,然后找到与之相关的user_id 它
您可以在格式的电子邮件中输入输入,并允许控制器完成其余操作
<%= form_for([@project, @project.project_members.build]) do |f| %>
<p>
<%= f.label :project_id %><br>
<%= f.text_field :project_id %>
</p>
<p>
<%= label_tag :email %><br>
<%= email_field_tag :email %>
</p>
<p>
<%= f.submit :Add, class: 'btn btn-info' %>
</p>
<% end %>
在控制器中,使用电子邮件找到用户
def create
@project_member = ProjectMember.new(member_params)
@user = User.find_by(email: params[:email])
@project_member.user_id = @user.id
@project_member.save
end
此外,您不需要在表单中明确提供project_id
。表单中的@project
会为您提供project_id
。你只需要让控制器进行映射
<%= form_for([@project, @project.project_members.build]) do |f| %>
<p>
<%= label_tag :email %><br>
<%= email_field_tag :email %>
</p>
<p>
<%= f.submit :Add, class: 'btn btn-info' %>
</p>
<% end %>
在控制器中,
def create
@project = Project.find(params[:project_id])
@project_member = @project.project_members.new(member_params)
@user = User.find_by(email: params[:email])
@project_member.user_id = @user.id
@project_member.save
end
答案 1 :(得分:0)
在您看来,将user_id
替换为user_email
字段:
<p>
<%= f.label :user_email %><br>
<%= f.text_field :user_email %>
</p>
在控制器中,获取email
def create
user = User.find_by_email(params[:project_member][:user_email]) # find the user by email
@project_member = ProjectMember.new(:project_id => params[:project_member][:project_id]) # create new project member with project id
@project_member.users << user # assign user to newly created project member
@project_member.save
end
private
def member_params
params.require(:project_member).permit(:user_email, :project_id)
end
希望它有所帮助!
注意:请确保我们通过电子邮件找到的用户是否存在!
答案 2 :(得分:0)
实现此目的的一种方法是将member_params
修改为
def member_params
member_params = params.require(:project_member).permit(:email, :project_id)
if (user_id = User.find_by_email(member_params[:email]).try(:id)).present?
member_params.merge!(user_id: user_id)
member_params.permit!
else
# display error
end
end
或者让你的params
保持原样
def member_params
params.require(:project_member).permit(:email, :project_id)
end
在你的控制器中,
def create
@project_member = ProjectMember.build_by(member_params)
if @project_member.save
# success
else
# failure
end
end
和模型,
def self.build_by(params)
project_member = self.new(params)
project_member.user_id = User.find_by_email(params[:email]).try(:id)
end
我认为,第二种选择更清洁,逻辑转向模型..