【问题标题】:Rails 3: validation, presence: true is only validating text field but not radio buttonRails 3:验证,存在:true 仅验证文本字段,但不验证单选按钮
【发布时间】:2012-06-11 23:50:33
【问题描述】:

所以我正在开发带有嵌套表单的 Rails 应用程序的这一部分。我无法让验证正常工作。所以父表单是存储问题的模型,子表单是存储答案的模型。

有 3 种不同类型的问题:数字(文本字段)、是/否(单选按钮)、同意/不同意(单选按钮)。

我在答案模型中有一个简单的验证:validates :value, presence: true

因此,例如,我创建了一个编号类型的问题,它会生成一个文本字段,如果我将其提交为空,则验证有效并且错误会呈现在页面上。但是,如果我选择其他 2 个选项之一,这两个选项都是单选按钮,我可以在不进行选择的情况下提交表单,并且验证不起作用。我在控制台中注意到只有问题被插入到数据库中,但答案不是(使用单选按钮形式);通常我会假设至少会传递 nil 值,但 INSERT 查询甚至不会出现。

I cheated a little by having a hidden field in the radio button forms, and creating a change handler that sets the value of the radio button to the hidden field whenever the radio button selected is changed.但是,我真的很想深入挖掘并找出真正的问题,因为在禁用 javascript 的情况下备份总是好的。

答案模型

class Answer < ActiveRecord::Base
  attr_accessible :value, :user_id, :meter_id, :question_id
  belongs_to :user
  belongs_to :question

  validates :value, presence: true, :numericality => true

  before_save :associate_with_meter_id
  before_save :associate_with_user_id

  def associate_with_meter_id
    self.meter_id = question.user.meter_id
  end

  def associate_with_user_id
    self.user_id = question.user.id
  end

end

问题模型

class Question < ActiveRecord::Base
    attr_accessible :description, :taxonomy, :user_id, :answers_attributes
  belongs_to :user
  has_many :answers

  accepts_nested_attributes_for :answers

  validates :description, presence: { :on => :create }
  validates :taxonomy, presence: { :on => :create }

  def relevance_score
    rand
  end

end

日志

Started POST "/questions" for 127.0.0.1 at 2012-06-12 09:21:25 -0400
Processing by QuestionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"knwvfB6q6Q7qoTprc/3R4Et3r13xWzpAB1Iq8FsRndQ=", "question"=>{"description"=>"How are you?", "taxonomy"=>"yesno"}, "submit_button"=>"Ask"}
  User Load (0.6ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 585460615 LIMIT 1
  SQL (0.1ms)  BEGIN
  SQL (4.3ms)  INSERT INTO `questions` (`avganswer`, `coeff`, `created_at`, `description`, `pval`, `quality`, `rank`, `responses`, `rsquare`, `skips`, `taxonomy`, `updated_at`, `user_id`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)  [["avganswer", nil], ["coeff", nil], ["created_at", Tue, 12 Jun 2012 13:21:25 UTC +00:00], ["description", "How are you?"], ["pval", 0.0], ["quality", 0.0], ["rank", nil], ["responses", nil], ["rsquare", 0.0], ["skips", nil], ["taxonomy", "yesno"], ["updated_at", Tue, 12 Jun 2012 13:21:25 UTC +00:00], ["user_id", 585460615]]
   (0.3ms)  COMMIT
  SQL (0.0ms)  BEGIN
   (0.0ms)  COMMIT
Redirected to http://localhost:3000/questions
Completed 302 Found in 14ms (ActiveRecord: 0.0ms)


Started GET "/questions" for 127.0.0.1 at 2012-06-12 09:21:25 -0400
Processing by QuestionsController#index as HTML
  User Load (0.3ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 585460615 LIMIT 1
  Question Load (1.3ms)  SELECT `questions`.* FROM `questions` WHERE `questions`.`user_id` = 585460615
  Rendered shared/_error_messages.html.erb (0.0ms)
  Rendered questions/_form.html.erb (23.9ms)
   (0.5ms)  SELECT COUNT(*) FROM `questions` 
  Rendered questions/index.html.erb within layouts/application (48.8ms)
  Question Load (1.6ms)  SELECT `questions`.* FROM `questions` 
   (0.4ms)  SELECT COUNT(*) FROM `questions` WHERE `questions`.`user_id` = 585460615
  Rendered /Users/gregorygrillone/.rvm/gems/ruby-1.9.3-p194/bundler/gems/gauges-58ad28a906b2/app/views/gauges/_gauge.html.erb (0.1ms)
  CACHE (0.0ms)  SELECT `questions`.* FROM `questions` 
  CACHE (0.0ms)  SELECT COUNT(*) FROM `questions` WHERE `questions`.`user_id` = 585460615
Completed 200 OK in 72ms (Views: 62.2ms | ActiveRecord: 4.2ms)


Started GET "/assets/application.css" for 127.0.0.1 at 2012-06-12 09:21:25 -0400
Served asset /application.css - 304 Not Modified (0ms)
[2012-06-12 09:21:25] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true


Started GET "/assets/application.js" for 127.0.0.1 at 2012-06-12 09:21:25 -0400
Served asset /application.js - 304 Not Modified (0ms)
[2012-06-12 09:21:25] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true

问题控制器

class QuestionsController < ApplicationController
  respond_to :html, :json

  def index
    @question = current_user.questions.new
    @questions = current_user.questions.all
  end

  def create
    @question = current_user.questions.new(params[:question])
    if !params[:update_button]
      if @question.valid?
        if params[:next_button] || !@question.save
          @questions = current_user.questions.all
          render 'index'
        elsif !params[:next_button] && params[:submit_button] && @question.save
          flash[:success] = "Your question and answer have been saved."
          respond_with @question, :location => questions_path
        end
      else
        @questions = current_user.questions.all
        render 'index'
      end
    else
      @questions = current_user.questions.all
      render 'index'
    end
  end

  def next
    @question = current_user.unanswered.first
    @answer = Answer.new(:question => @question, :user => current_user)
    respond_to do |format|
      format.js
    end
  end
end

【问题讨论】:

  • 请贴出相关的查看代码。此外,您应该发布模型的部分以供相互参考的问题和答案。验证和accepts_nested_attributes_for 也是如此。
  • 同时发布两种情况下传递的参数哈希,您可以从日志文件或服务器窗口中获取。
  • 你看到这个答案了吗:stackoverflow.com/questions/4112858/…
  • 是的,我之前做研究时确实看到了这一点。我试过了,但它不起作用(除了文本字段),单选按钮似乎甚至没有接受任何验证
  • 我刚刚发现,如果您进行了验证并且它失败了,则不会生成 INSERT 查询(这正是正在发生的事情),但它仍在呈现成功页面,所以也许它在我的问题控制器中(父窗体)。我会把它贴在上面,我知道它看起来有点难看,所以可能是导致问题的原因

标签: ruby-on-rails ruby validation nested-forms


【解决方案1】:

我认为您的视图代码没有正确创建表单结构。

您应该能够通过编写以您期望的格式发布参数的功能/控制器测试来确认您的控制器代码是否正确。 (比尝试将一半的应用程序发布到 StackOverflow 更好/更快的反馈!)

您将能够在不到一个小时的时间内创建一个体面的测试,而这些知识将使您在其他方面做得更好更快。相信我,学习如何正确测试代码是值得的。

一旦您证明您的控制器工作正常,您很可能会发现您的视图代码没有正确创建嵌套答案的表单输入。您可以从日志文件中看到它甚至没有尝试发布它们。

您可能希望将创建和更新操作分开,检查不同按钮的代码有点混乱,并且难以理解页面和控制器之间的“合同”。 (例如,如果下一个但不更新但提交......)这不是现在导致您的问题,而是您可能想要在它以后咬你之前清理的东西。

【讨论】:

  • 这很奇怪,我知道它甚至不会尝试发布答案,但这只会在没有给出值时发生(仅适用于单选按钮)。如果您选择一个选项,则该值被正确插入。
  • 哦,那是因为在这种情况下浏览器不会发布。它与单选按钮共同用于创建默认答案,他们必须选择一个或另一个。
  • 好吧,它会发布什么价值?如果单选按钮是男性/女性,并且他们没有选择一个,你想看到什么?你也许可以伪造它。搜索单选按钮发布问题,也许您会找到解决方法。或者只是强制默认
  • 现在有两组不同的单选按钮:是/否和同意/不同意(李克特量表)。所以我想要选择 1 个值。我已经进行了大量研究,并尝试使用名为 validates_inclusion_of 的辅助方法。它让您设置对输入有效的值,即 1(或是)。我试过了,没有运气。奇怪的是,只有在未选择任何内容时才会跳过验证;我尝试创建一个自定义验证方法,如果选择了单选按钮(并且它有效),该方法将失败,但是当我尝试使其失败时,如果没有值它只是跳过了验证
  • 还有,我只是想设置一个默认的选中单选按钮,但试图找到一个替代方案,因为我觉得它的可用性很差,因为如果用户不小心提交了表单而没有做出正确的选择他们可能会感到沮丧
猜你喜欢
  • 2014-11-18
  • 2023-03-13
  • 1970-01-01
  • 2023-04-06
  • 2012-05-12
  • 2015-09-01
  • 2012-12-01
  • 1970-01-01
相关资源
最近更新 更多