Проверка формы Rails - PullRequest
       16

Проверка формы Rails

22 голосов
/ 12 декабря 2008

У меня есть приложение Rails, которое позволяет пользователю создать запрос к базе данных, заполнив обширную форму. Я поинтересовался передовой практикой проверки параметров формы в Rails. Ранее у меня был results метод (тот, который отправляет форма), выполняющий следующие действия:

if params[:name] && !params[:name].blank?
  @name = params[:name]
else
  flash[:error] = 'You must give a name'
  redirect_to :action => 'index'
  return
end

Но для нескольких полей формы просмотр этого повторения для каждого стал утомительным. Я не мог просто вставить их все в какой-то цикл, чтобы проверить каждое поле, потому что поля настроены по-разному:

  • один ключ: params[:name]
  • ключ и субключ: params[:image][:font_size]
  • ожидается, что некоторые поля формы будут заполнены, только если было установлено другое поле

Etc. Это также было повторением, потому что я устанавливал flash[:error] для каждого отсутствующего / недействительного параметра и перенаправлял на один и тот же URL для каждого. Я перешел на использование before_filter, который проверяет все необходимые параметры формы и возвращает true, только если все в порядке. Затем метод my results продолжается, и переменные просто присваиваются без проверки:

@name = params[:name]

В моем validate_form методе у меня есть такие разделы кода:

if (
  params[:analysis_type][:to_s] == 'development' ||
  params[:results_to_generate].include?('graph')
)
  {:graph_type => :to_s, :graph_width => :to_s,
   :theme => :to_s}.each do |key, sub_key|
    unless params[key] && params[key][sub_key]
      flash[:error] = "Cannot leave '#{Inflector.humanize(key)}' blank"
      redirect_to(url)
      return false
    end
  end
end

Мне просто интересно, пойду ли я в этом вопросе наилучшим образом, или я упускаю что-то очевидное, когда дело доходит до проверки параметров. Я волнуюсь, что это все еще не самый эффективный метод, потому что у меня есть несколько блоков, в которых я присваиваю значение flash[:error], затем перенаправляю на тот же URL, а затем возвращаю false.

Изменить, чтобы уточнить: Причина, по которой у меня нет этой проверки в модели (ях) в настоящее время по двум причинам:

  • Я не пытаюсь собрать данные от пользователя, чтобы создать или обновить строку в базе данных. Ни одна из данных, отправленных пользователем, не сохраняется после выхода из системы. Все это используется правильно, когда они отправляют его для поиска в базе данных и генерируют некоторые вещи.
  • Форма запроса принимает данные, относящиеся к нескольким моделям, и другие данные, которые вообще не относятся к модели. Например. Тип и тема графика, как показано выше, не связаны с какой-либо моделью, они просто передают информацию о том, как пользователь хочет отобразить свои результаты.

Редактировать, чтобы показать улучшенную технику: Теперь я использую исключения для конкретного приложения, благодаря статье Джамиса Бака Поднятие правильного исключения . Например:

def results
  if params[:name] && !params[:name].blank?
    @name = params[:name]
  else
    raise MyApp::MissingFieldError
  end

  if params[:age] && !params[:age].blank? && params[:age].numeric?
    @age = params[:age].to_i
  else
    raise MyApp::MissingFieldError
  end
rescue MyApp::MissingFieldError => err
  flash[:error] = "Invalid form submission: #{err.clean_message}"
  redirect_to :action => 'index'
end

Ответы [ 4 ]

25 голосов
/ 12 декабря 2008

Вы можете попробовать active_form (http://github.com/cs/active_form/tree/master/lib/active_form.rb) - просто ActiveRecord минус содержимое базы данных. Таким образом, вы можете использовать все элементы проверки AR и обрабатывать свою форму так же, как любая другая модель.

class MyForm < ActiveForm
  validates_presence_of :name
  validates_presence_of :graph_size, :if => # ...blah blah 
end

form = MyForm.new(params[:form])
form.validate
form.errors
6 голосов
/ 12 декабря 2008

Похоже, вы выполняете проверку в контроллере, попробуйте поместить ее в модель, она лучше подходит для такого рода вещей.

2 голосов
/ 27 января 2011

Если бы вы снова решили проблему сегодня, вы могли бы создать модель для набора параметров запроса и использовать встроенные в Rails валидации, Rails 3 делает это намного проще с ActiveModel :: Validations см. этот пост .

0 голосов
/ 30 июня 2018

Модель

class Person 
    include ActiveModel::Validations
    include ActiveModel::Conversion
    extend ActiveModel::Naming

    attr_accessor :name
    attr_accessor :email


    validates_presence_of :name,:message => "Please Provide User Name"
    validates_presence_of :email,:message => "Please Provide Email"
end

Обратите внимание, что вам не обязательно сохранять / сохранять модель для проверки.

Контроллер

@person.name= params["name"]
@person.email= params["email"]
@person.valid?

Тот, кого ты назвал .valid? метод на модели, ошибки будут заполнены внутри объекта @person. Следовательно,

View

<%if @person.errors.any? %>
     <%@person.errors.messages.each do|msg| %>
          <div class="alert alert-danger">
            <%=msg[0][1]%>
          </div>
     <%end%>
<%end%>
...