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
Sum 2 Hashes Attributes with the Same Key
Rails Link_To External Site, Url Is Attribute of User Table, Like: @Users.Website
Cannot Load Such File -- Readline (Loaderror) When Running Heroku Create --Stack Cedar
Form Submitted Twice, Due to :Remote=>True
Multiple Sinatra Apps Using Rack-Mount
Rails: Validation in Model VS Migration
Sidekiq: Ensure All Jobs on the Queue Are Unique
Is There a Shorter Way to Require a File in the Same Directory in Ruby
Ruby on Rails: Debugging Rake Tasks
How to Use Redis in a Multi-Threaded Rails Environment? (Puma/Sidekiq)
Ruby: Proc.New { 'Waffles' } VS. Proc { 'Waffles' }
Rails How to Update a Column After Saving
How to Test Code Coverage for Rails Erb Templates
Calculating Difference in Time Between Two Time Objects
Using a Class Object in Case Statement