3
\$\begingroup\$

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"

\$\endgroup\$
4
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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? ;)

http://www.sitepoint.com/10-ruby-on-rails-best-practices/

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.