How to Validate a Non-Model Form in Rails 3

How do I validate a non-model form in Rails 3?

With Rails 3 you can extend "plain old Ruby objects" with some
ActiveModel extensions like Validations etc. ActiveRecord is extension of ActiveModel with DB support. Here is a very good Railscast describing it with easy example:

In Rails 3 the non-database
functionality of Active Record is
extracted out into Active Model. This
allows you to cleanly add validations
and other features to tableless
models. http://railscasts.com/episodes/219-active-model

Rails validation of non-model input

From what you've written, I would say you want to look at attr_accessor and use ActiveRecord to validate your form data:

#app/models/model.rb
Class Model < ActiveRecord::Base
attr_accessor :your, :inputs
validates :your, :inputs, presence: true
end

This will create virtual attributes which you can then validate using the standard ActiveRecord validation functionality. I believe that, as your model will typically create instance methods for your datatable's attributes, you'll be able to achieve the same functionality with attr_accessor attributes

As mentioned by @Mohammed, you'll then be able to validate the inputs by creating an instance of the model with your data:

#app/controllers/your_controller.rb
Class Controller < ApplicationController
def create
@model = Model.new(input_params)
@model.valid?
end
private
def input_params
params.require(:model).permit(:your, :inputs)
end
end

ROR: Validate Non-model fields in model file

Try this:

put a virtual attribute in the model.

class MyModel < ActiveRecord::Base

attr_accessor :non_model_field
validates :non_model_field, presence: true # or whatever other validations you want

end

RoR: Validate non-model field before create controller method

If I were you, I would start out by keeping all of this logic in the controller and use a filter to find the city:

class CustomersController < ApplicationController
before_action :find_city, only: [:create, :update]

def create
@customer = Customer.new(customer_params)
#read the city name, since this is requested by city name (string) and it shoud be "id" in the system
@customer.city_id = @city.try(:id) # This returns `nil` if the city was not found
respond_to do |format|
if @customer.save
format.html { redirect_to @customer, notice: 'Customer was successfully created.' }
format.json { render action: 'show', status: :created, location: @customer }
else
format.html { render action: 'new' }
format.json { render json: @customer.errors, status: :unprocessable_entity }
end
end
end

private

def find_city
@city = City.find_by(name: params[:city][:name]) # No need for strong parameters for this
end
end

Then make sure you're validating the presence of city_id in your Customer class:

class Customer < ActiveRecord::Base
validates :city_id, presence: true
end

Later on, if you find that you need this logic to be extracted from the controller, then consider looking at creating a service object or a form object. Because this is a simple case (only 2 classes are involved), I would hold off on creating those constructs for now though. The controller layer is sufficient enough to handle this simple logic.

Why not move the logic directly into the model? I can tell you from experience that you do not want to mess your model up with tons of logic involving other model classes. Customer should not really know much about City in my opinion.

Validate non-model field

Found. You may want to add a virtual attribute in the model.

.........

attr_accessor :not_on_db
.........

validates_presence_of :not_on_db,
validates_length_of :not_on_db, :within => 1..5
.........


Related Topics



Leave a reply



Submit