从_form或控制器保存的当前用户ID [英] current user id saved from _form or controller
问题描述
我正在使用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 $ c中设置适当的外键$ c>对象。
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屋!