I want to create a Rails (2.1 and 2.2) model with ActiveRecord validations, but without a database table. What is the most widely used approach? I've found some plugins that claim to offer this functionality, but many of them don't appear to be widely used or maintained. What does the community recommend I do? Right now I am leaning toward coming up with my own solution based on this blog post.
-
1The blog post linked is now dead. – Jeremy B. Feb 04 '11 at 13:29
-
1http://www.prestonlee.com/2007/12/29/rails-20-validations-without-extending-activerecordbase/ and yet alive under a new name. – Tim Snowhite Mar 21 '11 at 19:22
-
http://web.archive.org/web/20100716123520/http://www.prestonlee.com/2007/12/29/rails-20-validations-without-extending-activerecordbase/ because it seems to be down again – GDR Oct 03 '11 at 23:44
-
1This seems to be a duplicate of http://stackoverflow.com/questions/937429/activerecordbase-without-table which actually proposes a better solution. – Michal Dec 07 '12 at 10:37
13 Answers
There is a better way to do this in Rails 3: http://railscasts.com/episodes/219-active-model

- 2,485
- 1
- 25
- 33
-
I voted you up because I agree this is a cleaner and better way to do it especially if starting a new project. However, I did find John Topley's solution to be better on a project where lots of code still needs to think your model is a subclass of ActiveRecord::Base. One specific example of this method not easily working is if your code relies on a 3rd party plugin that relies on ActiveRecord. – Tony Sep 21 '11 at 21:17
-
6In Rails 4 there is also ActiveModel::Model, which includes many of the ActiveModel modules and some other magic, to make you feel your (non-persisted or custom-persisted) model like an ActiveRecord model. – nandilugio Sep 17 '14 at 12:47
This is an approach I have used in the past:
In app/models/tableless.rb
class Tableless < ActiveRecord::Base
def self.columns
@columns ||= [];
end
def self.column(name, sql_type = nil, default = nil, null = true)
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default,
sql_type.to_s, null)
end
# Override the save method to prevent exceptions.
def save(validate = true)
validate ? valid? : true
end
end
In app/models/foo.rb
class Foo < Tableless
column :bar, :string
validates_presence_of :bar
end
In script/console
Loading development environment (Rails 2.2.2)
>> foo = Foo.new
=> #<Foo bar: nil>
>> foo.valid?
=> false
>> foo.errors
=> #<ActiveRecord::Errors:0x235b270 @errors={"bar"=>["can't be blank"]}, @base=#<Foo bar: nil>>

- 113,588
- 46
- 195
- 237
-
3Works well and very lightweight. Rails 2.3 will complain a bit about the lack of a table at script/console, but adding "self.abstract_class = true" solves that (without preventing instantiation). – Andrew Hodgkinson Mar 23 '10 at 15:43
-
This seems hideous to me. Why bother inheriting from ActiveRecord::Base if you don't want a database back-end? There are other libraries that provide validation functionality that don't assume a database backend. – David J. Jun 23 '10 at 20:58
-
@Rekin See http://stackoverflow.com/questions/3416484/simple-ruby-input-validation-library – David J. Dec 11 '10 at 22:12
-
-
Just for record: first option (http://stackoverflow.com/questions/3416484/simple-ruby-input-validation-library) is for Rails 3 only. – gorn Jul 18 '11 at 19:25
There is easier way now:
class Model
include ActiveModel::Model
attr_accessor :var
validates :var, presence: true
end
ActiveModel::Model
code:
module ActiveModel
module Model
def self.included(base)
base.class_eval do
extend ActiveModel::Naming
extend ActiveModel::Translation
include ActiveModel::Validations
include ActiveModel::Conversion
end
end
def initialize(params={})
params.each do |attr, value|
self.public_send("#{attr}=", value)
end if params
end
def persisted?
false
end
end
end

- 5,198
- 5
- 40
- 44
I think the blog post you are linking is the best way to go. I would only suggest moving the stubbed out methods into a module not to pollute your code.

- 4,349
- 2
- 24
- 40
-
I'm with Honza and I think that post is your only option if you need AR's validations in your POCO's. Good luck. – Mike Breen Nov 25 '08 at 18:18
-
11
-
1Rails introduced [ActiveModel as their way of solving this problem](https://guides.rubyonrails.org/active_model_basics.html#mode) - there is an answer covering this below https://stackoverflow.com/a/34354961/1511504 – notapatch Oct 13 '19 at 19:59
just create a new file ending in ".rb" following the conventions you're used to (singular for file name and class name, underscored for file name, camel case for class name) on your "models/" directory. The key here is to not inherit your model from ActiveRecord (because it is AR that gives you the database functionality). e.g.: for a new model for cars, create a file called "car.rb" in your models/ directory and inside your model:
class Car
# here goes all your model's stuff
end
edit: btw, if you want attributes on your class, you can use here everything you use on ruby, just add a couple lines using "attr_accessor":
class Car
attr_accessor :wheels # this will create for you the reader and writer for this attribute
attr_accessor :doors # ya, this will do the same
# here goes all your model's stuff
end
edit #2: after reading Mike's comment, I'd tell you to go his way if you want all of the ActiveRecord's functionality but no table on the database. If you just want an ordinary Ruby class, maybe you'll find this solution better ;)

- 167
- 4
There's a screencast about non-Active Record model, made up by Ryan Bates. A good place to start from.
Just in case you did not already watch it.

- 710
- 4
- 9
-
again this doesn't solve the posters problem of using AR's validations. – Mike Breen Nov 25 '08 at 18:16
-
What about marking the class as abstract?
class Car < ActiveRecord::Base
self.abstract = true
end
this will tell rails that the Car class has no corresponding table.
[edit]
this won't really help you if you'll need to do something like:
my_car = Car.new

- 2,610
- 1
- 19
- 13
Use the Validatable gem. As you say, there are AR-based solutions, but they tend to be brittle.
Anybody has ever tried to include ActiveRecord::Validations
and ActiveRecord::Validations::ClassMethods
in a non-Active Record class and see what happens when trying to setup validators ?
I'm sure there are plenty of dependencies between the validation framework and ActiveRecord itself. But you may succeed in getting rid of those dependencies by forking your own validation framework from the AR validation framework.
Just an idea.
Update: oopps, this is more or less what's suggested in the post linked with your question. Sorry for the disturbance.

- 710
- 4
- 9
You ought to checkout the PassiveRecord plugin. It gives you an ActiveRecord-like interface for non-database models. It's simple, and less hassle than fighting ActiveRecord.
We're using PassiveRecord in combination with the Validatable gem to get the OP's desired behaviour.

- 3,910
- 1
- 23
- 21
-
These days I would probably include ActiveModel and whatever else I needed. – Tate Johnson Jan 15 '13 at 07:59
Do like Tiago Pinto said and just don't have your model inherit from ActiveRecord::Base. It'll just be a regular Ruby class that you stick in a file in your app/models/ directory. If none of your models have tables and you're not using a database or ActiveRecord at all in your app, be sure to modify your environment.rb file to have the following line:
config.frameworks -= [:active_record]
This should be within the Rails::Initializer.run do |config|
block.

- 30,930
- 33
- 155
- 222
-
just like Tiago Pinto's answer this won't help our friend use the AR validations in his class. – Mike Breen Nov 25 '08 at 18:17