gpt4 book ai didi

ruby-on-rails - RSpec - 无法获取 Controller 中的所有关联属性

转载 作者:数据小太阳 更新时间:2023-10-29 07:18:59 34 4
gpt4 key购买 nike

你好程序员和开发人员!!!,我是 RoR 的初学者,我在 Rails 中创建了一个简单的项目来学习它的工作原理,所以在那个项目中,我在为 create 编写规范时遇到了问题 Controller 的方法。当我试图在规范文件中传递对象的关联属性时,在 Controller 中它没有获得所有属性。

subjects_controller.rb文件的create方法中。
我创建了一个名为attr的变量> 在此变量中,我存储了从 subjects_controller_spec.rb 文件发送的所有值。

attr=(params.require(:subject).permit(:name)).merge(:classroom_ids=>params[:subject][:classroom_ids],:school_ids=>params[:subject][:school_ids])

现在,如果我在控制台中使用 p attr 打印 attr 的值,它的输出就是我想要的确切输出,即

{"name"=>"Computer", "classroom_ids"=>["1", "2"], "school_ids"=>["1"]}

但是,现在我正在做 @subject = Subject.new(attr) 并且 @subject 的打印值给出以下输出

#<Subject id: nil, name: "Computer", created_at: nil, updated_at: nil>

在运行测试后,我的测试失败了,然后我打印了错误 p @subject.errors 它给了我下面的输出

#<ActiveModel::Errors:0x007fc35444a218 @base=#<Subject id: nil, name: "Computer", created_at: nil, updated_at: nil>, @messages={:school_ids=>["is not a number"], :classroom_ids=>["is not a number"]}>

所以,我的实际问题是为什么 subjects_controller.rb 中的 @subject 没有 的值classroom_idsschool_ids?如果有任何解决方案或建议,请帮助我解决这个问题。



下面我为您提供了所有必要的详细信息以了解实际问题

ruby 版本 2.2.4
Rails 版本 4.2.0
数据库 MySQL

模型文件subject.rb

class Subject < ActiveRecord::Base
has_and_belongs_to_many :schools
has_and_belongs_to_many :teachers
has_and_belongs_to_many :classrooms
has_and_belongs_to_many :students

validates_presence_of :name, :school_ids, :classroom_ids
validates_numericality_of :school_ids, :classroom_ids
end



Controller 文件subjects_controller_spec.rb

require 'rails_helper'

RSpec.describe SubjectsController, type: :controller do
before(:each) do
@school1 = FactoryGirl.create(:school)
@classroom1 = FactoryGirl.create(:classroom, :school_id=>@school1.id)
@classroom2 = FactoryGirl.create(:classroom, :school_id=>@school1.id)
@subject = FactoryGirl.build(:subject)
@subject.classrooms<<@classroom1
@subject.classrooms<<@classroom2
@subject.schools<<@school1
end
context "POST create" do
it "should be success" do
# p @subject
# p @subject.classrooms
# p @subject.classroom_ids
attributes=@subject.attributes.merge(:classroom_ids=>@subject.classroom_ids,:school_ids=>@subject.school_ids)

# In below line, I'm sending all the values to the controller to create a new subject.

post :create, :subject=>attributes

response.status.should eq 201
end
end
end



Controller 文件subjects_controller.rb

class SubjectsController < ApplicationController
before_action :set_subject, only: [:show, :edit, :update, :destroy]

# GET /subjects
def index
@subjects = Subject.all
end

# GET /subjects/1
def show
end

# GET /subjects/new
def new
@subject = Subject.new
end

# GET /subjects/1/edit
def edit
end



# POST /subjects
def create
attr=(params.require(:subject).permit(:name)).merge(:classroom_ids=>params[:subject][:classroom_ids],:school_ids=>params[:subject][:school_ids])

p attr ### here it prints all the values which I want to create subject.###

@subject = Subject.new(attr)

p @subject ### here is the actual problem, It's not printing all the values that need to create a new subject.###

if @subject.save
redirect_to @subject, notice: 'Subject was successfully created.', status: :created
else
p @subject.errors
render :new, status: :unprocessable_entity
end
end



# PATCH/PUT /subjects/1
def update
if @subject.update(subject_params)
redirect_to @subject, notice: 'Subject was successfully updated.', status: :ok
else
render :edit, :status => :unprocessable_entity
end
end

# DELETE /subjects/1
def destroy
@subject.destroy
redirect_to subjects_url, notice: 'Subject was successfully destroyed.'
end

private
# Use callbacks to share common setup or constraints between actions.
def set_subject
@subject = Subject.find(params[:id])
end

# Only allow a trusted parameter "white list" through.
def subject_params
params.require(:subject).permit(:name, :school_ids, :classroom_ids)
end
end



工厂文件subjects.rb

FactoryGirl.define do
factory :subject do
name "Computer"
end
end



RSpec 测试报告

rspec spec/controllers/subjects_controller_spec.rb 
{"name"=>"Computer", "classroom_ids"=>["1", "2"], "school_ids"=>["1"]}
#<Subject id: nil, name: "Computer", created_at: nil, updated_at: nil>
#<ActiveModel::Errors:0x007fcdfe8f1a28 @base=#<Subject id: nil, name: "Computer", created_at: nil, updated_at: nil>, @messages={:school_ids=>["is not a number"], :classroom_ids=>["is not a number"]}>
F

Failures:

1) SubjectsController POST create should be success
Failure/Error: response.status.should eq 201

expected: 201
got: 422

(compared using ==)
# ./spec/controllers/subjects_controller_spec.rb:21:in `block (3 levels) in <top (required)>'

Deprecation Warnings:

Using `should` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }` instead. Called from /Users/vishal/project/school_system/spec/controllers/subjects_controller_spec.rb:21:in `block (3 levels) in <top (required)>'.


If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
`config.raise_errors_for_deprecations!`, and it will turn the
deprecation warnings into errors, giving you the full backtrace.

1 deprecation warning total

Finished in 0.40113 seconds (files took 3.03 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/controllers/subjects_controller_spec.rb:14 # SubjectsController POST create should be success

Coverage report generated for RSpec to /Users/vishal/project/school_system/coverage. 49 / 332 LOC (14.76%) covered.


更多详情可以引用this Github link .

提前感谢您的帮助。

最佳答案

[ "1", "2"] 不是整数数组而是字符串! @subject 有 classroom_ids 和 school_ids,但是 params 始终将输入值视为 String,因此在您的 Subject 模型中会出现验证错误。所以尝试下面将 String 转换为 Integer:

params[:subject][:classroom_ids].map(&:to_i) 
params[:subject][:school_ids].map(&:to_i)

这个怎么样?

在 Controller 中没有map方法的情况下恢复:

params[:subject][:classroom_ids] 
params[:subject][:school_ids]

在我的 PC 中,通过从您的 github 链接修改 Subject 模型,并通过了测试。你能试试这个吗?

Class Subject < ActiveRecord::Base
has_and_belongs_to_many :schools
has_and_belongs_to_many :teachers
has_and_belongs_to_many :classrooms
has_and_belongs_to_many :students

validates_presence_of :name, :school_ids, :classroom_ids
validate :validate_classroom_ids
validate :validate_school_ids

private

def validate_classroom_ids
if classroom_ids.any?{ |id| !id.is_a?(Integer) }
errors.add(:classroom_ids, 'is not a number')
return false
end
end

def validate_school_ids
if school_ids.any?{ |id| !id.is_a?(Integer) }
errors.add(:school_ids, 'is not a number')
return false
end
end
end

关于ruby-on-rails - RSpec - 无法获取 Controller 中的所有关联属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39551552/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com