I'm new to rails. I am using Redis instead of something backed w/ ActiveRecord. I need to validate the presence of location, categories, start_date, and end_date. I then need to check that start_date and end_date are valid dates, that start_date comes before end_date. And that location matches a regex [A-Za-z_]. And that categories.length> 0. Since the start_date and end_date parameters in my model's setters are Date objects, should I check for valid dates and convert them in my controller. Then have my model's setters take care of the rest of the validation?
I just don't know where to put the validations: in my model or controller?
Model:
class MyThingie
def self.set_x(location, categories, start_date, end_date, value)
updates = {}
for date in (start_date .. end_date)
# ...
end
$redis.mset(*updates.flatten)
end
def self.set_y(location, categories, default)
updates = {}
for category in categories
# ...
end
$redis.mset(*updates.flatten)
end
def self.set_z(location, categories, start_date, end_date, block)
if block
updates = {}
for date in (start_date .. end_date)
# ...
end
$redis.mset(*updates.flatten)
else
deletes = []
for date in (start_date .. end_date)
# ...
end
$redis.del(*deletes)
end
end
end
Controller:
class MyThingieController < ApplicationController
# ...
def create
begin
method = params[:method]
location = params[:location]
categories = params[:categories]
s_start_date = params[:start_date]
s_end_date = params[:end_date]
if method == "normal"
value = params[:value]
start_date = Date.strptime(s_start_date, "%m/%d/%Y")
end_date = Date.strptime(s_end_date, "%m/%d/%Y")
MyThingie.set_x(location, categories, start_date, end_date, value)
elsif method == "default"
default = params[:default]
MyThingie.set_y(location, categories, default)
elsif method == "block"
block = params[:block]
start_date = Date.strptime(s_start_date, "%m/%d/%Y")
end_date = Date.strptime(s_end_date, "%m/%d/%Y")
MyThingie.set_z(location, categories, start_date, end_date, block)
else
raise "Invalid form submit"
end
rescue Exception => e
errors = [e.message]
respond_to do |format|
format.json do
json = Jsonify::Builder.new
json.errors errors
a = json.compile!
render :status => 400, :json => a
end
end
else
respond_to do |format|
format.json do
json = Jsonify::Builder.new
json.msg "Update successful."
a = json.compile!
render :json => a
end
end
end
end
Here the keys are like
mythingie:location:date = value
mythingie:location:default = default
mythingie:location:date:z = "true"
2 Answers 2
In your model.
You can include ActiveModel::Validations directly in your model without relying on ActiveRecord for persistence.
See ActiveModel::Validations & the date_validator gem
A quick example more relevant to you;
class MyThingie
include ActiveModel::Validations
validates :start_date, :presence => true
validates :end_date, :presence => true
# Check out the date_validator gem, it allows things like
validates_date_of :end_date, :after => :start_date
validates_format_of :location, :with => /[A-Za-z]/
# ...
end
You should not validate your model in controller. Imagine situation, where you need to create another controller, for example it will be the API controller with same logic. What you will do? Copy your code and paste? And what about unit testing? ;)