【问题标题】:Rails: Using form fields that are unassociated with a model in validationsRails:在验证中使用与模型无关的表单字段
【发布时间】:2011-03-20 15:04:19
【问题描述】:

在 Ruby on Rails 应用程序中,我尝试使用与验证中的模型无关的字段中的信息。

这里以模型的一部分为例(整个模型变得有点大):

class Scorecard < ActiveRecord::Base
  belongs_to :course
  belongs_to :user

  validate :attributes_consistency

  def attributes_consistency
    # Executed for all scorecards.  Checks if the user completed the hole attributes correctly
    if ( params[:no_fairways] and any_fairways? and !only_nine? ) or ( params[:no_fairways] and !any_h1_to_h9_score_blank and any_h1_to_h9_fairway? and only_nine? ) or ( params[:no_fairways] and !any_h10_to_h18_score_blank and any_h10_to_h18_fairway? and only_nine? )
      errors.add_to_base("You inidicated that you missed all the fairways, but you also marked one or more fairways in the scorecard.  Either uncheck the fairways mistakenly marked or uncheck the 'No fairways' checkbox.")
    end
    if ( params[:no_girs] and any_girs? and !only_nine? ) or ( params[:no_girs] and !any_h1_to_h9_score_blank and any_h1_to_h9_gir? and only_nine? ) or ( params[:no_girs] and !any_h10_to_h18_score_blank and any_h10_to_h18_gir? and only_nine? )
      errors.add_to_base("You inidicated that you missed all the greens, but you also marked one or more greens in the scorecard.  Either uncheck the marked greens on the scorecard or uncheck the 'No GIRs' checkbox.")
    end
  end # attributes_consistency


  def any_h1_to_h9_score_blank?
    h1_score.blank? or h2_score.blank? or h3_score.blank? or h4_score.blank? or h5_score.blank? or h6_score.blank? or h7_score.blank? or h8_score.blank? or h9_score.blank?
  end
  def any_h10_to_h18_score_blank?
    h10_score.blank? or h11_score.blank? or h12_score.blank? or h13_score.blank? or h14_score.blank? or h15_score.blank? or h16_score.blank? or h17_score.blank? or h18_score.blank?
  end

  def any_h1_to_h9_fairway?
    h1_fairway? or h2_fairway? or h3_fairway? or h4_fairway? or h5_fairway? or h6_fairway? or h7_fairway? or h8_fairway? or h9_fairway?
  end
  def any_h10_to_h18_fairway?
    h10_fairway? or h11_fairway? or h12_fairway? or h13_fairway? or h14_fairway? or h15_fairway? or h16_fairway? or h17_fairway? or h18_fairway?
  end

  def any_h1_to_h9_gir?
    h1_gir? or h2_gir? or h3_gir? or h4_gir? or h5_gir? or h6_gir? or h7_gir? or h8_gir? or h9_gir?
  end
  def any_h10_to_h18_gir?
    h10_gir? or h11_gir? or h12_gir? or h13_gir? or h14_gir? or h15_gir? or h16_gir? or h17_gir? or h18_gir?
  end

那么如何从模型中访问params

【问题讨论】:

    标签: ruby-on-rails ruby validation forms


    【解决方案1】:

    不要让参数潜入模型。在这种情况下,拥有控制器是没有意义的。相反,请查看Railscasts 的这一集,其中讨论了不会进入数据库但仍可用于验证的虚拟属性。

    虚拟属性不需要对应的模型属性。定义类的本地属性,例如保持状态的@no_fairways

    class ScoreCard < ActiveRecord::Base
      # define attributes and accessors for both fields
      attr_accessor :no_fairways, :no_girs
    
      ..
    end
    

    现在在你的表单中,你可以写:

    <% form_for @scorecard %>
      <%= f.check_box :no_fairways %>
    <% end %>
    

    【讨论】:

    • 这将是一个很好的解决方案,但你能举个例子说明我如何实现这个吗?在那个特定的 Railscast 中,“虚拟属性”实际上是操纵真实属性的方法。我没有可以与no_fairwaysno_girs 关联的属性。
    • @James - 虚拟属性不必与任何数据库属性相关联。您可以定义同样有效的实例属性。更新了答案。
    • 请注意,与 checkbox 关联的 attr 不会有 trythy 或 falsy 值。默认情况下,check_box 生成的标记在未选中时生成 "0" 字符串,在选中时生成 "1"。即使"0".present? 也是真实的。
    【解决方案2】:

    找到了解决方案,不过感谢术语,“虚拟属性”有助于谷歌搜索。

    实现此目的最简洁的方法是创建不属于数据库但仍属于模型的属性。就我而言,我将其放入模型中:

    attr_accessor :no_fairways
    attr_accessor :no_girs
    

    就这么简单!现在@scorecard.no_fairways@scorecard.no_girs 的作用与任何其他属性一样,但它们不是数据库的一部分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-22
      • 1970-01-01
      • 2014-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多