Rails 5, 没有 ID 找不到 User 。您可以通过表单传递对象吗?
Rails 5, Couldnt't find User without and ID . Can you pass an Object through a form?
我正在尝试编写用户向其技能集添加技能(属于用户、技术和级别)的能力。
我在 skills/new 中有一个 simple_for_for。html.erb:
<%= simple_form_for [ @user, @skill ] do |f| %>
<p>Select Tech</p>
<div>
<%= f.collection_select :technology_id, @techs, :id, :name%>
</div>
<p>Select Level</p>
<div>
<%= f.collection_select :level_id, @levels, :id, :name%>
</div>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
技能控制器: 新操作正在将技术和级别对象列表传递给 simple_form_for 因此用户可以 select 的选项是所有技术和级别的列表(例如,技术:Ruby,级别:初级)。
class SkillsController < ApplicationController
before_action :authenticate_user!
def index
@skills = policy_scope(Skill)
end
def new
@techs = Technology.all
@levels = Level.all
@skill = Skill.new
@user = current_user
authorize @skill
end
def create
skill = Skill.new(skill_params)
authorize skill
if skill.save
redirect_to projects_path
else
render :action => "new", @user => params[:user_id], @skill => skill
end
end
private
def skill_params
params.require(:skill).permit(:user_id, :technology_id, :level_id)
end
end
我有几个问题:
else子句在保存新技能失败后没有正确发送@user和@skill到表单,但我不知道语法是否正确。
实际问题:表单是否可以传递与选项 selected 关联的技术和级别 ID 而不是对象本身?我试过像这样手动查找所有技能组件,这会导致“无法找到没有 ID 的用户”错误:
def create
skill = Skill.new()
technology = Technology.find(skill_params[:technology_id])
level = Level.find(skill_params[:level_id])
user = User.find(skill_params[:user_id])
skill.user = user
skill.technology = technology
skill.level = level
authorize skill
if skill.save
redirect_to projects_path
else
render :action => "new", @user => user, @skill => skill
end
end
private
def skill_params
params.require(:skill).permit(:technology_id, :level_id, :user_id)
end
在您的创建操作中,您可以在尝试 create/save 之前设置 @user
和 @skill
,然后您可以在 else 子句中渲染新的:
def create
@user = current_user
@skill = Skill.new(skill_params)
authorize @skill
if @skill.save
redirect_to projects_path
else
render :new
end
end
是的,您可以传递 ID,因为 ID 将保存在数据库中。
错误的原因 Couldn't find a user without an id, probably because the skill_params doesn't have the user_id.您使用 current_user
辅助方法而不是通过表单获得 user_id。
首先确保您已设置从用户到技能的关联,您可以从中建立新记录:
class User
has_many :skills
end
如果您的应用程序只允许用户将技能添加到他们自己的帐户中,您应该只从会话中获取当前用户:
def create
@skill = current_user.skills.new(skill_params)
authorize @skill
if @skill.save
redirect_to projects_path
else
render :new
end
end
请注意,这消除了完全嵌套表单和路由的需要:
resources :skills
<%= simple_form_for @skill do |f| %>
# ...
<% end %>
我正在尝试编写用户向其技能集添加技能(属于用户、技术和级别)的能力。
我在 skills/new 中有一个 simple_for_for。html.erb:
<%= simple_form_for [ @user, @skill ] do |f| %>
<p>Select Tech</p>
<div>
<%= f.collection_select :technology_id, @techs, :id, :name%>
</div>
<p>Select Level</p>
<div>
<%= f.collection_select :level_id, @levels, :id, :name%>
</div>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
技能控制器: 新操作正在将技术和级别对象列表传递给 simple_form_for 因此用户可以 select 的选项是所有技术和级别的列表(例如,技术:Ruby,级别:初级)。
class SkillsController < ApplicationController
before_action :authenticate_user!
def index
@skills = policy_scope(Skill)
end
def new
@techs = Technology.all
@levels = Level.all
@skill = Skill.new
@user = current_user
authorize @skill
end
def create
skill = Skill.new(skill_params)
authorize skill
if skill.save
redirect_to projects_path
else
render :action => "new", @user => params[:user_id], @skill => skill
end
end
private
def skill_params
params.require(:skill).permit(:user_id, :technology_id, :level_id)
end
end
我有几个问题:
else子句在保存新技能失败后没有正确发送@user和@skill到表单,但我不知道语法是否正确。
实际问题:表单是否可以传递与选项 selected 关联的技术和级别 ID 而不是对象本身?我试过像这样手动查找所有技能组件,这会导致“无法找到没有 ID 的用户”错误:
def create
skill = Skill.new()
technology = Technology.find(skill_params[:technology_id])
level = Level.find(skill_params[:level_id])
user = User.find(skill_params[:user_id])
skill.user = user
skill.technology = technology
skill.level = level
authorize skill
if skill.save
redirect_to projects_path
else
render :action => "new", @user => user, @skill => skill
end
end
private
def skill_params
params.require(:skill).permit(:technology_id, :level_id, :user_id)
end
在您的创建操作中,您可以在尝试 create/save 之前设置 @user
和 @skill
,然后您可以在 else 子句中渲染新的:
def create
@user = current_user
@skill = Skill.new(skill_params)
authorize @skill
if @skill.save
redirect_to projects_path
else
render :new
end
end
是的,您可以传递 ID,因为 ID 将保存在数据库中。
错误的原因 Couldn't find a user without an id, probably because the skill_params doesn't have the user_id.您使用 current_user
辅助方法而不是通过表单获得 user_id。
首先确保您已设置从用户到技能的关联,您可以从中建立新记录:
class User
has_many :skills
end
如果您的应用程序只允许用户将技能添加到他们自己的帐户中,您应该只从会话中获取当前用户:
def create
@skill = current_user.skills.new(skill_params)
authorize @skill
if @skill.save
redirect_to projects_path
else
render :new
end
end
请注意,这消除了完全嵌套表单和路由的需要:
resources :skills
<%= simple_form_for @skill do |f| %>
# ...
<% end %>