从_form或控制器保存的当前用户ID [英] current user id saved from _form or controller

查看:62
本文介绍了从_form或控制器保存的当前用户ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Devise管理用户,我的目标是将当前用户与创建的记录一起保存。



我尝试将当前用户保存在控制器或_form,但无论哪种方式都失败了!



谢谢大家的帮助。



我的记录模型

  class Record< ActiveRecord :: Base 
#Associations
Emirates_to:user


#验证
验证:title,:user,状态:true
end

我的记录控制器

  class RecordsController< ApplicationController 
before_action:find_record,仅:[:show,:edit,:update,:destroy]

def create
@record = Record.new(record_params)

if @ record.save
redirect_to @record
else
@records = Record.all
渲染'index'
end
end

def更新
,如果@ record.update(record_params)
flash [:notice] =记录已成功更新
redirect_to @record
否则
呈现'edit'
end
end

private

def find_record
@record = Record.find(params [:id])
结束

def record_params
params.require(:record).permit(:title,:description,:user_id).merge(user:current_user) #根据建议
结束
结束

我的Rspec

 要求'rails_helper'

描述RecordsController做
let(:record){create(:re cord)}
let(:user){create(:user)}
let(:title){我想放入记录中的某些标题}
let(:description ){我想放入记录的描述}


describe #create做
它使用给定的标题和描述创建新记录
期望做
post:创建,记录:{title:标题,描述:description,user_id:user}
end.to更改{Record.count} .by(1)

Expect(response).to redirect_to(assigns [:record])

Expect(assigns [:record] .title).to eq(title)
Expect(assigns) [:record] .description).to eq(description)
end

它未能创建记录并返回索引页执行
Expect(post:create ,record:{description:description})。to render_template(:index)
Expect(assigns [:records])。eq(Record.all)
end
end

描述 #update,执行
,找到记录并执行ts新的给定值
put:update,{id:record.id,record:{标题:标题,描述:描述}}

record.reload
期望(record.title).to eq(title)
Expect(record.description).to eq(description)

Expect(flash [:notice])。to eq(已成功更新)
结束

它未能创建记录并返回到编辑页面做了
Expect(put:update,{id:record.id,记录:{title:}})。to render_template(:edit)
结束
结束
结束

现在保存了当前用户,Rspec在创建和更新时抛出错误:

  1)RecordsController#create创建具有给定标题和描述
的新记录失败/错误:post:create,record:{标题:标题,描述:描述,user_id:用户}
NoMethodError:$ bil的b $ b未定义方法身份验证:NilClass
#./app /controllers/records_controller.rb:42:in`record_params'
#./app/controllers/records_controller.rb:9:in`create'
#./spec/controllers/records_controller_spec.rb:36 :in在< top(必填)>中的块(4级)中/spec/controllers/records_controller_spec.rb:35:在< top(必填)>中的块(3级)中;''
#-e:1:in'< main>'

2)RecordsController#create无法创建记录并返回到索引页
失败/错误:expect(post:create,record:{description:description})。to render_template(:index)
NoMethodError:
未定义的方法'authenticate'为nil:NilClass
#./app/ controllers / records_controller.rb:42:在`record_params'
#./app/controllers/records_controller.rb:9:在`create'
#./spec/controllers/records_controller_spec.rb:46:在< top(必填)>中的'block(3个级别)'中
#-e:1:在`< main>'

3)RecordsController#update find t他记录并设置了新的给定值
故障/错误:put:update,{id:record.id,record:{标题:标题,描述:描述}}
NoMethodError:
未定义nil:NilClass
#./app/controllers/records_controller.rb:42:在`record_params'中的方法'authenticate'
#./app/controllers/records_controller.rb:20:in在'update'中
#./spec/controllers/records_controller_spec.rb:62:in在< top(必填)>中的块(3级)中
#-e:1:in在< main>中'

4)RecordsController#update无法创建记录,并返回到编辑页面
失败/错误:Expect(put:update,{id:record.id,record:{title :}})。to render_template(:edit)
NoMethodError:
未定义方法'authenticate'为nil:NilClass
#./app/controllers/records_controller.rb:42:in `record_params'
#./app/controllers/records_controller.rb:20:in`update'
#./spec/controllers/records_contro ller_spec.rb:72:在< top(必填)>'


解决方案

要添加到 bo-oz 的答案(应该有效)中,您还需要查看



每次在Rails中创建关联时,必须在数据库中设置外键以启用 ActiveRecord (Rails中的对象关联生成器)将适当的数据组合在一起:

 #app / models / user.rb 
class User< ActiveRecord :: Base
has_many:records
end

#app / models / record.rb
class Record< ActiveRecord:Base
#请参见上图-必须在模式中包含user_id :)
归属于:user
end

-



您遇到的问题是您没有设置<$创建记录时使用c $ c> user 外键



您的记录表应该有一个 user_id 外键,这样,当Rails提取一个 Record 对象时,它将能够找到与之关联的用户



作为解释说,您可以通过设置 @ record.user 来实现,也可以在参数中进行设置:

 #app / controllers / records_controller.rb 
class RecordsController< ApplicationController
def创建
@record = Record.new record_params
@ record.save ..........
end

private

def record_params
params.require(:record).permit(......)。merge(user:current_user)
结束
结束

这两个答案都将在新的 Record 对象。


I'm using Devise to manage users and my goal get the current user to be saved with the created record.

I have tried to save the current user in the controller or in the _form, but either ways it has failed!

Thank you all for your help.

My record Model

class Record < ActiveRecord::Base
  #Associations
  belongs_to :user


  # Validations
  validates :title, :user, presence: true
end

My record Controller

class RecordsController < ApplicationController
  before_action :find_record, only: [:show, :edit, :update, :destroy]

  def create
    @record = Record.new(record_params)

    if @record.save
      redirect_to @record
    else
      @records = Record.all
      render 'index'
    end
  end

  def update
    if @record.update(record_params)
      flash[:notice] = "The record was updated successfully"
      redirect_to @record
    else
      render 'edit'
    end
  end

  private

    def find_record
      @record = Record.find(params[:id])
    end

    def record_params
      params.require(:record).permit(:title, :description, :user_id).merge(user: current_user) # as suggested 
    end
end

My Rspec

require 'rails_helper'

describe RecordsController do
  let(:record) { create(:record) }
  let(:user) { create(:user) }
  let(:title) { "Some title I would like to put in my record" }
  let(:description) { "description I would like to put in my record" }


  describe "#create" do
    it "creates a new record with the given title and description" do
      expect do
        post :create, record: { title: title, description: description, user_id: user }
      end.to change { Record.count }.by(1)

      expect(response).to redirect_to(assigns[:record])

      expect(assigns[:record].title).to eq(title)
      expect(assigns[:record].description).to eq(description)
    end

    it "fails to create a record and returns to the index page" do
      expect(post :create, record: { description: description }).to render_template(:index)
      expect(assigns[:records]).to eq(Record.all)
    end
  end

  describe "#update" do
    it "find the records and sets the new given values" do
      put :update, { id: record.id, record: { title: title, description: description } }

      record.reload
      expect(record.title).to eq(title)
      expect(record.description).to eq(description)

      expect(flash[:notice]).to eq("The record was updated successfully")
    end

    it "fails to create a record and returns to the edit page" do
      expect(put :update, { id: record.id, record: { title: "" } }).to render_template(:edit)
    end
  end
end

Now with the current user being saved Rspec throws me errors in create and update:

1) RecordsController#create creates a new record with the given title and description
     Failure/Error: post :create, record: { title: title, description: description, user_id: user }
     NoMethodError:
       undefined method `authenticate' for nil:NilClass
     # ./app/controllers/records_controller.rb:42:in `record_params'
     # ./app/controllers/records_controller.rb:9:in `create'
     # ./spec/controllers/records_controller_spec.rb:36:in `block (4 levels) in <top (required)>'
     # ./spec/controllers/records_controller_spec.rb:35:in `block (3 levels) in <top (required)>'
     # -e:1:in `<main>'

  2) RecordsController#create fails to create a record and returns to the index page
     Failure/Error: expect(post :create, record: { description: description }).to render_template(:index)
     NoMethodError:
       undefined method `authenticate' for nil:NilClass
     # ./app/controllers/records_controller.rb:42:in `record_params'
     # ./app/controllers/records_controller.rb:9:in `create'
     # ./spec/controllers/records_controller_spec.rb:46:in `block (3 levels) in <top (required)>'
     # -e:1:in `<main>'

  3) RecordsController#update find the records and sets the new given values
     Failure/Error: put :update, { id: record.id, record: { title: title, description: description } }
     NoMethodError:
       undefined method `authenticate' for nil:NilClass
     # ./app/controllers/records_controller.rb:42:in `record_params'
     # ./app/controllers/records_controller.rb:20:in `update'
     # ./spec/controllers/records_controller_spec.rb:62:in `block (3 levels) in <top (required)>'
     # -e:1:in `<main>'

  4) RecordsController#update fails to create a record and returns to the edit page
     Failure/Error: expect(put :update, { id: record.id, record: { title: "" } }).to render_template(:edit)
     NoMethodError:
       undefined method `authenticate' for nil:NilClass
     # ./app/controllers/records_controller.rb:42:in `record_params'
     # ./app/controllers/records_controller.rb:20:in `update'
     # ./spec/controllers/records_controller_spec.rb:72:in `block (3 levels) in <top (required)>'

解决方案

To add to bo-oz's answer (which should work), you also need to look into foreign keys. Trying to set record_id in your record form simply won't work, and I think demonstrates a misunderstanding in your interpretation of how the system works with this important piece of technology.

Specifically, you need to make sure your user_id attribute is populated before you save the new record. This is a relational database specification, not Rails:

Each time you create an association in Rails, it has to have foreign keys set in the database to enable ActiveRecord (the object association builder inside Rails) to combine the appropriate data together:

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :records
end

#app/models/record.rb
class Record < ActiveRecord:Base
   #see diagram above -- this has to have user_id in the schema :)
   belongs_to :user
end

--

The problem you're having is that you're not setting your user foreign key when you create a record.

Your records table should have a user_id foreign key, so that when Rails pulls out a Record object, it will be able to find the User who's associated to it.

As bo-oz explained, you can achieve this by setting @record.user, you can also set it in the params:

#app/controllers/records_controller.rb
class RecordsController < ApplicationController
   def create
      @record = Record.new record_params
      @record.save ..........
   end

   private

   def record_params
      params.require(:record).permit(......).merge(user: current_user)
   end
end

Both these answers would set the appropriate foreign key inside your new Record object.

这篇关于从_form或控制器保存的当前用户ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆