Rails单表继承验证

时间:2017-07-10 15:14:40

标签: ruby-on-rails validation single-table-inheritance

我的应用中有一个Request模型。在不同的页面上,我需要不同的验证,例如在/contacts上我需要验证很多字段,而在“稍后再打电话”弹出窗口中,我需要仅验证电话号码和名称。

我的问题是:数据已保存,但未经过验证且type也未保存。

结构: request.rb

class Request < ApplicationRecord

  self.inheritance_column = :_type_disabled

  def self.types
      %w(ContactRequest CallMeBackRequest)
  end

  scope :contacts, -> { where(type: 'ContactRequest') } 
  scope :callmebacks, -> { where(type: 'CallMeBackRequest') } 
end

routes.rb中:

resources :contact_requests, only: [:new, :create], controller: 'requests', type: 'ContactRequest'
resources :call_me_back_requests, only: [:new, :create], controller: 'requests', type: 'CallMeBackRequest'

contact_request.rb:

class ContactRequest < Request
  validates :name, :phone, :email, :company_name, presence: true

  def self.sti_name
    "ContactRequest"
  end
end

call_me_back_request.rb:

class CallMeBackRequest < Request
  validates :name, :phone, presence: true

  def self.sti_name
    "CallMeBack"
  end
end

requests_controller.rb:

class Front::RequestsController < FrontController
  before_action :set_type

  def create
    @request = Request.new(request_params)

    respond_to do |format|
      if @request.save
        format.js
      else
        format.js { render partial: 'fail' }

      end
    end
  end

  private

  def set_request
    @request = type_class.find(params[:id])
  end

  def set_type
     @type = type
  end

  def type
      Request.types.include?(params[:type]) ? params[:type] : "Request"
  end

  def type_class 
      type.constantize 
  end

  def request_params
    params.require(type.underscore.to_sym).permit(Request.attribute_names.map(&:to_sym))
  end
end

我的表单以:

开头
=form_for Request.contacts.new, format: 'js', html: {class: 'g-contact__sidebar-right g-form'}, remote: true do |f|

我尝试使用ContactRequest.new - 结果是一样的。

当我按下控制台时我得到了什么:

  • Request.contacts.create!(name: "something") - 确实已保存,未应用任何验证(为什么?)。没有填充type字段 - 为什么?
  • ContactRequest.create!(name: "something") - 未保存,已应用验证
  • ContactRequest.create!(name: ..., all other required fields) - 确实已保存,但字段type为空 - 为什么?

无论我使用哪种形式 - ContactRequest.newRequest.contacts.new - 都不会应用验证,也无法正确设置字段type

有人能指出我正确的方向吗?我主要使用this tutorial和其他SO问题,但没有成功。

1 个答案:

答案 0 :(得分:0)

想出来 - 因为我没有使用这些联系人的专用页面和路径,即contact_requests_path和相应的new.html.haml,我需要传递type参数作为隐藏的领域。

所以我的表单现在看起来像这样:

=form_for ContactRequest.new, format: 'js', html: {class: 'g-contact__sidebar-right g-form'}, remote: true do |f|
  =f.hidden_field :type, value: "ContactRequest"

考虑验证 - 我不知道自己做了什么,但在重新启动服务器几次后,它们现在正在工作。我记得真正改变的唯一一个就是这里的名字:

class CallMeBackRequest < Request
  validates :name, :phone, presence: true

  def self.sti_name
    "CallMeBack" <- changed it from "CallMeBack" to "CallMeBackRequest"
  end
end