【问题标题】:Rails 5, Couldnt't find User without and ID . Can you pass an Object through a form?Rails 5,找不到没有和 ID 的用户。您可以通过表单传递对象吗?
【发布时间】:2020-08-13 12:38:31
【问题描述】:

我正在尝试编写用户将技能(属于用户、技术和级别)添加到其技能集中的能力。

我在技能/new.html.erb 中有一个 simple_for_for:

  <%= 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 %>

Skills Controller:New 操作将技术和关卡对象列表传递给 simple_form_for,因此用户可以选择的选项是所有技术和关卡的列表(例如,技术: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到表单,但是不知道语法是否正确。

实际问题:表单是否可以传递与所选选项相关联的技术和级别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

【问题讨论】:

  • 请添加请求日志 - 检查请求参数

标签: ruby-on-rails ruby forms action


【解决方案1】:

首先确保您已经建立了从用户到技能的关联,您可以根据这些关联建立新记录:

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 %>

【讨论】:

    【解决方案2】:

    在您的创建操作中,您可以在尝试创建/保存它之前设置@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 将保存在数据库中。

    Couldnt find a user without an id 错误的原因可能是因为 Skill_params 没有 user_id。您使用 current_user 辅助方法而不是通过表单获取 user_id。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-01
      • 2020-05-18
      • 1970-01-01
      • 2019-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多