在create action上使用current_user的问题(嵌套属性)

时间:2017-08-23 00:44:36

标签: ruby-on-rails controller

我想将用户模型与简历模型相关联。创建操作完美无需用户和简历之间的关联。在表单中,我可以使用carrierwave上传pdf文件并将其与简历模型(download_file:string)相关联。 我希望一个用户只能有一个简历。我更新了用户并恢复了模型:

user.rb

class User < ActiveRecord::Base

  has_one :resume, :dependent => :destroy

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

resume.rb

class Resume < ActiveRecord::Base
  belongs_to :user
  mount_uploader :download_file, DownloadFileUploader
end

我还在简历模型上的add user_id列上运行了迁移:

schema.rb

ActiveRecord::Schema.define(version: 20170822204938) do

  create_table "resumes", force: :cascade do |t|
    t.string   "download_file"
    t.datetime "created_at",    null: false
    t.datetime "updated_at",    null: false
    t.integer  "user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

end

我已经通过在params中添加user_id更新了我的简历控制器,并且我还更新了create动作,因此可以传递来自current_user的user_id键:

resumes_controller.rb

 class ResumesController < ApplicationController
  around_filter :catch_not_found
  before_action :find_resume, only: [ :show, :edit, :update, :destroy]
  before_action :authenticate_user!

  def show
  end

  def new
    @resume = Resume.new
  end

  def create
    @resume = current_user.resume.new(resume_params)
    if @resume.save
      redirect_to @resume
    else
      render :new
    end
  end

  def edit
  end

  def update
    if @resume.update resume_params
      redirect_to @resume, notice: "Your resume was successfully saved!"
    else
      render 'edit'
    end
  end

  def destroy
    @resume.destroy
    redirect_to new_resume_path, notice: "Your resume was successfully deleted!"
  end

  private

  def resume_params
    params.require(:resume).permit( :user_id, :download_file, :remove_download_file)
  end

  def find_resume
    @resume = Resume.find(params[:id])
  end

  def catch_not_found
    yield
    rescue ActiveRecord::RecordNotFound
    redirect_to(root_url, :notice => 'Record not found')
  end

end

不幸的是,我得到了一个未定义的方法`new&#39;为零:NilClass&#34;错误:

enter image description here

我还删除,创建并迁移了数据库,但它仍然无法正常工作。

我错过了什么?我怎样才能做到这一点?

如果您还有其他问题,请告诉我。

2 个答案:

答案 0 :(得分:2)

您收到错误是因为当您致电current_user.resume时,您正在调用该关系,该关系不存在,因此它是nil所以当您再调用new时,实际发生的是nil.new。如果要为当前用户构建新的简历对象,则应使用has_one关系构建方法:

@resume = current_user.build_resume(resume_params)

答案 1 :(得分:1)

虽然这已经被重复了几次,但问题是你要查询一个尚不存在的关系。

有几个选项可以使用[build][1]方法,或者你可以做类似于

的方法
def new
  @resume = Resume.new(resume_params)
end

def create
  @resume = current_user.build_resume(resume_params)
  if @resume.save
    ~~~~
  else
    ~~~~
  end
end

我发布类似答案的原因实际上是提到使用byebug gem来帮助调试此类问题

通过在创建/新方法中放置触发器byebug,您可以自由地看到current_user resume@resume current_user.resume等等解决也是如此,根据我的经验,通常可以帮助解决很多这些问题。