【问题标题】:Rails 4 'permit' and 'count by one' errorsRails 4 'permit' 和 'count by one' 错误
【发布时间】:2014-03-15 23:18:00
【问题描述】:

我正在通过关注Agile Web Development with Rails 4 学习 Rails。我在第 9 章,刚刚完成单元测试。为了更好地理解我正在阅读的内容,我正在逐步构建自己的应用程序,以及我必须按照本书构建的应用程序。这本书经历了建立一个电子商店,我的应用程序是一个病人记录保存应用程序。

我正在编写测试。我生成了两个脚手架DoctorsPatients。对于Patients,一切正常,因为我实际上是在以与本书并行的方式做所有事情。

虽然对于Doctors,我遇到了一个问题,app/controller/doctors_controller.rb 中的[params] 中的有效负载是作为String 而不是Hash 传递的。更具体地说,我得到的错误是:

DoctorsControllerTest
    ERROR (0:00:00.094) test_should_create_doctor
          undefined method `permit' for "625417172":String
        @ app/controllers/doctors_controller.rb:72:in `doctor_params'
          app/controllers/doctors_controller.rb:27:in `create'
          [...]

我仔细检查了代码,一切都类似于Patients控制器,但我没有问题!在做了一些online research 之后,我设法使用attributes 绕过了这个错误:

[...]
test "should create doctor" do
        assert_difference('Doctor.count') do
            post :create, doctor: @doctor.attributes # instead of @doctor
        end

        assert_redirected_to doctor_path(assigns(:doctor))
end
[...]

但是当我运行rake test 时出现以下错误:

DoctorsControllerTest
     FAIL (0:00:00.182) test_should_create_doctor
          "Doctor.count" didn't change by 1.
          Expected: 3
            Actual: 2

如果有人可以通过解决可能报告的第一个错误(在恕我直言,这是我的问题的真正根源)或至少是第二个错误,我会很高兴有人能给我一些关于如何通过此测试的提示,这样我就可以了继续我的项目。

编辑:共享请求的代码:

Doctor 我的模型是:

class Doctor < ActiveRecord::Base

    validates :name, presence: {message: "Συμπληρώστε το όνομα του ιατρού"}
    validates :surname, presence: {message: "Συμπληρώστε το επώνυμο του ιατρού"}
    validates :birthday, presence: {message: "Συμπληρώστε την ημερομηνία γεννήσεως ιατρού"}
    validates :gender, presence: {message: "Συμπληρώστε το γένος του ιατρού"}
    validates :identity_number, presence: {message: "Συμπληρώστε τον αριθρμό αστυνομικής ταυτότητας του ιατρού"}
    validates :identity_number_pd, presence: {message: "Συμπληρώστε την πόλη του αστυνομικού τμήματος που εξέδωσε την ταυτότητα"}
    validates :father_name, presence: {message: "Συμπληρώστε το πατρώνμου ιατρού"}
    validates :doctor_specialty, presence: {message: "Συμπληρώστε την ειδικότητα του ιατρού"}
    validates :doc_medical_association_city, presence: {message: "Συμπληρώστε την πόλη του ιατρικού συλλόγου που είναι εγγεγραμένος ο ιατρός"}
    validates :home_phone, presence: {message: "Συμπληρώστε τον αριθμό τηλεφώνου οικίας του ιατρού"}
    validates :mobile_phone, presence: {message: "Συμπληρώστε το κινητό τηλέφωνο του ιατρού"}
    validates :city, presence: {message: "Συμπληρώστε την πόλη κατοικίας του ιατρού"}
    validates :country, presence: {message: "Συμπληρώστε χώρα της κατοικίας του ιατρού"}
    validates :postal_code, presence: {message: "Συμπληρώστε τον ταχυδρομικό κώδικα της οικίας του ιατρού"}
    validates :image_url, allow_blank: true, format: {
        with: %r{\.(gif|jpg|png)\Z}i, message: "Η μορφή της φωτογραφίας πρέπει να είναι PNG, JPG ή GIF"
    }
    validates :email, :allow_blank => true,:uniqueness => { :case_sensitive => false }, :email_format => {:message => 'Η διεύθυνση email που έχετε εισαγάγει είναι λανθασμένη'}

    # Εξωτερικές συναρτήσεις (methods) για validation
    validate :birthday_is_date # γεννέθλια
    validate :doc_medical_association_no_check

    # Έλεγχος ορθότητας ημερομηνίας γεννήσεως. Στην βάση δεδομένων η ημερομηνίες θα σωθούν με το Αμερικάνικο σύστημα
    # πιο συγκεκριμένα: Χρονιά/μήνα/ημέρα, π.χ. 1972/11/24
    def birthday_is_date 
        errors.add(:birthday, "Λάθος στην ημερομηνία γεννήσεως!") unless Chronic.parse(birthday)
    end

    # Έλεγχος για μοναδικό άριθμο μητρώου ιατρού. Εδώ το validation μπορεί να δημιουργήσει πρόβλημα. Πρέπει να εισαχθεί και τρίτο 'condition' - 14/03/14
    def doc_medical_association_no_check
        if doc_medical_association_no
            errors.add(:doc_medical_association_no, "Ο αριθμός μητρώου υπάρχει είδη στην βάση δεδομένων!") if Doctor.exists?(["doc_medical_association_no = ? and not surname = ?", self.doc_medical_association_no, self.surname])
        end
    end
end

Doctor 的测试控制器是:

require 'test_helper'

class DoctorsControllerTest < ActionController::TestCase
    setup do
        @doctor = doctors(:alex)

        @update = {
            name: "Απόστολος",
            surname: "Παπαδόπουλος",
            gender: "Άνδρας",
            birthday: Date.parse('1981-08-01'),
            identity_number: "ΑT12314",
            identity_number_pd: "Ξάνθης",
            image_url: "ap_pap.jpg",
            father_name: "Στέλιος",
            doctor_specialty: "Πνευμονολόγος",
            doc_medical_association_city: "ΑΘήνα",
            doc_medical_association_no: "12345",
            home_phone: "+30 1234567",
            mobile_phone: "+30 1234567",
            home_address: "Τεστ 32",
            city: "Αθήνα",
            country: "Ελλάδα",
            postal_code: "12345",
            email: "papa@somemail.com"
        }
    end

    test "should get index" do
        get :index
        assert_response :success
        assert_not_nil assigns(:doctors)
    end

    test "should get new" do
        get :new
        assert_response :success
    end

    test "should create doctor" do
        assert_difference('Doctor.count') do
            post :create, doctor: @doctor # or @doctor.attributes but with the 'count by 1' error
        end

        assert_redirected_to doctor_path(assigns(:doctor))
    end

    test "should show doctor" do
        get :show, id: @doctor
        assert_response :success
    end

    test "should get edit" do
        get :edit, id: @doctor
        assert_response :success
    end

    test "should update doctor" do
        patch :update, id: @doctor, doctor: @update
        assert_redirected_to doctor_path(assigns(:doctor))
    end

    test "should destroy doctor" do
        assert_difference('Doctor.count', -1) do
            delete :destroy, id: @doctor
        end

        assert_redirected_to doctors_path
    end
end

当然doctor(:alex) 是我的固定装置。

最后,controller for Doctor 是:

class DoctorsController < ApplicationController
  before_action :set_doctor, only: [:show, :edit, :update, :destroy]

  # GET /doctors
  # GET /doctors.json
  def index
    @doctors = Doctor.all
  end

  # GET /doctors/1
  # GET /doctors/1.json
  def show
  end

  # GET /doctors/new
  def new
    @doctor = Doctor.new
  end

  # GET /doctors/1/edit
  def edit
  end

  # POST /doctors
  # POST /doctors.json
  def create
    @doctor = Doctor.new(doctor_params)

    respond_to do |format|
      if @doctor.save
        format.html { redirect_to @doctor, notice: 'Doctor was successfully created.' }
        format.json { render action: 'show', status: :created, location: @doctor }
      else
        format.html { render action: 'new' }
        format.json { render json: @doctor.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /doctors/1
  # PATCH/PUT /doctors/1.json
  def update
    respond_to do |format|
      if @doctor.update(doctor_params)
        format.html { redirect_to @doctor, notice: 'Doctor was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @doctor.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /doctors/1
  # DELETE /doctors/1.json
  def destroy
    @doctor.destroy
    respond_to do |format|
      format.html { redirect_to doctors_url }
      format.json { head :no_content }
    end
  end

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

    # Never trust parameters from the scary internet, only allow the white list through.
    def doctor_params
      params.require(:doctor).permit(:name, :surname, :gender, :birthday, :identity_number, :identity_number_pd, :image_url, :father_name, :doctor_specialty, :doc_medical_association_city, :doc_medical_association_no, :home_phone, :mobile_phone, :home_address, :city, :country, :postal_code, :email, :notes)
    end
end

【问题讨论】:

  • 请分享模型详细信息以及您如何设置@doctor。
  • 我添加了所有相关部分。如果您需要更多信息,请告诉我。

标签: ruby-on-rails testing


【解决方案1】:

count by 1 问题显然是由不健康的验证引起的。我正在使用导致问题的电子邮件验证器。因此,如果有人遇到同样的问题,请尝试一一禁用app/models/your_model_validations.rb,看看效果如何。

【讨论】:

    猜你喜欢
    • 2012-05-10
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 2021-08-01
    • 2013-08-27
    相关资源
    最近更新 更多