Внимательно читаем этот guide, лучше все равно не расскажешь. Итак, валидации используются, чтобы быть уверенными, что только валидные данные сохраняются в вашу базу данных.
Замечательно, но возникает как минимум один вопрос. Как быть, если для нас нет необходимости сохранять данные в базу данных? Возможно, данные формы, веденные пользователем, должны быть использованы лишь единожды, как использовать валидации Ruby on Rails в этом случае?
Active Model. Use validations in model without any DB relations на форуме.
Знакомство с темой оптимально начать с материалов форума, описывающих классический пример реализации Rails validation на основе ActiveModel. Здесь же разберем чуть более сложный случай, построив погодный веб-информер, способный получить актуальное состояние погоды по версии OpenWeatherMap - по ID города, введенному в поле формы.
На собственно форме отправки данных здесь останавливаться не будем, сделайте ее тем способом, который посчитаете нужным; хелперы Rails или же simple_form к вашим услугам, сгодится на первых порах и самый обычный HTML. Пример того, как отобразить сообщение о проваленной валидации Active Model на веб-страничке вашего rails-app - также доступен на форуме.
Примем, что имя поля формы, посредством которого реализован ввод ID населенного пункта - "request", т.е. name="request". И вот что у нас получилось:
code.rb (или вариант с rescue вместо elsif; там же, по ссылке на форуме)
class FormController < ApplicationController
include Action
def weather
@weather = Form.new(form_params)
if @weather.valid?
@lookup = Weather.call([params[:request]].join(","))
if @lookup.empty?
flash.now[:error] = 'Error. Invalid ID: ' + params[:request] + '. Data not received. Server response: ' + response.status.to_s
else
flash.now[:notice] = 'Success. ID: ' + params[:request] + '. Server response: ' + response.status.to_s
end
end
end
private
def form_params
params.permit(:request)
end
end
action.rb
module Action
extend ActiveSupport::Concern
class Weather
include HTTParty
key_openweathermap = ENV['KEY_OPENWEATHERMAP']
base_uri 'http://api.openweathermap.org/data/2.5/group?appid=' + key_openweathermap + '&units=metric'
format :json
#call the api with HTTParty and parse the JSON response
def self.call list_ids
response = HTTParty.get(base_uri + '&id=' + list_ids)
body = JSON.parse(response.body)
# Rails.logger.debug response.body
body.fetch('list'){[]}.compact
end
#create a hash to store city : temp values
def self.make_hash list, value
hash = Hash.new
list.each do |l|
temp = l["main"][value]
city = l["name"]
hash[city] = temp
end
end
#create hash with city: cloud cover
def self.cloud_hash list
hash = Hash.new
list.each do |l|
cloud = l["clouds"]["all"]
city = l["name"]
hash[city] = cloud
end
end
end
form.rb
class Form
include ActiveModel::Model
attr_accessor :request
validates :request, presence: true, numericality: { only_integer: true }, length: {in:6..7}
end
Ну вот как-то так. Разумеется, варианты улучшений/исправлений всегда приветствуются.