我的应用中有一个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.new
或Request.contacts.new
- 都不会应用验证,也无法正确设置字段type
。
有人能指出我正确的方向吗?我主要使用this tutorial和其他SO问题,但没有成功。
答案 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