I am trying to create a Active Record tableless Model. My user.rb looks like this
class User < ActiveRecord::Base
class_inheritable_accessor :columns
Few things:
Firstly you are using the Rails2 approach outlined in Railscast 193 when really you should be using the Rails 3 approach, outlined in Railscast 219
You probably don't want to inherit from ActiveRecord::Base when doing this sort of thing.
Read Yehuda Katz's blog post on this.
Just remove:
class_inheritable_accessor :columns
And it should work, even with associations just like a model with a table.
For Rails >= 3.2 there is the activerecord-tableless gem. Its a gem to create tableless ActiveRecord models, so it has support for validations, associations, types.
When you are using the recommended way to do it in Rails 3.x there is no support for association nor types.
Don't inherit your class from ActiveRecord::Base
.
If a model inherits from ActiveRecord::Base as you would expect a model class to,it wants to have a database back-end.
As mentioned by stephenmurdoch
in rails 3.0+ you can use the method outlined in railscasts 219
I had to make a slight modification to get this to work:
class Message
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :name, :email, :content
validates_presence_of :name
validates_format_of :email, :with => /^[-a-z0-9_+\.]+\@([-a-z0-9]+\.)+[a-z0-9]{2,4}$/i
validates_length_of :content, :maximum => 500
def initialize(attributes = {})
unless attributes.nil?
attributes.each do |name, value|
send("#{name}=", value)
end
end
end
def persisted?
false
end
end
class Tableless
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
def self.attr_accessor(*vars)
@attributes ||= []
@attributes.concat( vars )
super
end
def self.attributes
@attributes
end
def initialize(attributes={})
attributes && attributes.each do |name, value|
send("#{name}=", value) if respond_to? name.to_sym
end
end
def persisted?
false
end
def self.inspect
"#<#{ self.to_s} #{ self.attributes.collect{ |e| ":#{ e }" }.join(', ') }>"
end
end