如何在Ruby on Rails中验证表单中至少一个字段的存在

时间:2015-11-19 21:54:37

标签: ruby-on-rails ruby validation ruby-on-rails-4

我有一个包含多个列的搜索模型。这些列中填充了form_for @search do |s|中的公共app/views/searchings/index.html.erb。所以问题是我在该视图上有三个字段,每个字段都由它自己的复选框激活。我想验证至少一个字段的存在。我测试时没有经过验证,当禁用输入字段时,其值为nil。这是代码:

应用程序/模型/ searching.rb

  class Searching < ActiveRecord::Base
      belongs_to :user

      validate :capacidad_num
      validate :has_a_field

      def has_a_field
        arr = [self.tipo?, self.capacidad?, self.ubicacion_cont?, self.free_to?, self.free_from?]
        if !arr.include?(true)
          self.errors.add(:base, 'Debes ingresar al menos one parameter de búsqueda')
        end
      end

      def capacidad_num
        if self.capacidad?
          if !(self.capacidad.to_i != 0)
            self.error.add(:capacidad, 'tiene que ser un número')
          end
        end
      end

  end

应用程序/控制器/ searchings_controller.rb

class SearchingsController < ApplicationController
    before_action :get_search, only: [:show]

    def index

      @couches = Couch.all
      @tipos = Tipoc.all
      @search = Searching.new

    end

    def show
      #...show stuff not important
    end


    def create
      @search = Searching.new(params.permit(:tipo, :ubicacion_cont, :capacidad))

      respond_to do |format|
        if @search.save
          format.html { redirect_to @search, notice: "Mostrando resultados de búsqueda" }
          format.json { render :show, status: :created, location: @search }
        else
          format.html { render :index }
          format.json { render json: @search.errors, status: :unprocessable_entity }
        end
     end
   end

   private
   def get_search
     @search = Searching.find(params[:id])
   end

end

如果有帮助,这是此模型的架构:

create_table "searchings", force: :cascade do |t|
 t.integer  "tipo"
 t.string   "ubicacion_cont"
 t.integer  "capacidad"
 t.date     "free_from"
 t.date     "free_to"
 t.datetime "created_at",       null: false
 t.datetime "updated_at",       null: false
end

我尝试使用包含每个字段的布尔值的数组来验证至少一个字段的存在,但它似乎不起作用。每次我在表单上输入值时都会给出错误。

3 个答案:

答案 0 :(得分:1)

我不确定魔术布尔检查(只是在属性名称中添加?)是否像这样工作。我会尝试这样的事情:

def has_a_field
  fields = [:tipo, :ubicacion_cont, :capacidad, :free_to, :free_from]

  unless fields.any? { |field| self.send(field).present? }
    errors.add(:base, 'Debes ingresar al menos one parameter de búsqueda')
  end
end

答案 1 :(得分:1)

试试这个: -

def has_a_field
    arr = [self.tipo, self.capacidad, self.ubicacion_cont, self.free_to, self.free_from]
    arr_with_present_val = arr.select(&:presence)
    if arr_with_present_val.blank?
        self.errors.add(:base, 'Debes ingresar al menos one parameter de búsqueda')
        return false    
    end
end

答案 2 :(得分:0)

我得到了解决方案的另一种方法,并且运行良好。在def create内的控制器中,我检查params[:searching]是否为零。如果是,请显示警告消息。

def create

  if params[:searching].nil?

    redirect_to new_searching_path, alert: 'Debes ingresar al menos un parámetro'

  else

    #do the new and save stuff

  end

end

在使用byebug并检查我在params内的def create中收到的内容后,我最终得到了此解决方案。 我知道这不是轨道编程的一些好习惯,但是对于我想要的东西,它就像一个魅力。