Looks like this method doesn't work anymore in rails 3.1. So, does someone have a working solution?
Actually, I've found this gist. It solves problems with columns_hash
and column_defaults
errors from the railscast's solution but I get ActiveRecord::ConnectionNotEstablished
error all the time when I try to write some attribute.
Any thoughts?
The simplest tableless model in Rails 3.1 is:
class Session
include ActiveModel::Validations
include ActiveModel::Conversion
extend ActiveModel::Naming
attr_accessor :email, :password
validates :email, :presence => true
validates :password, :presence => true
def initialize(attributes = {})
if attributes
attributes.each do |name, value|
send("#{name}=", value)
end
end
end
def persisted?
false
end
end
The ActiveModel::Validations is optional (only if validations are used). Also the constructor is not required (but highly desireable).
For Rails / ActiveRecord 5.0 you need to redefine private def self.load_schema!
to avoid checking the table_name
. Also, notice a little hack for the column
method (Type).
Here's the complete listing for Tableless model for Rails 5.0 / ActiveRecord 5.0
class Tableless < ActiveRecord::Base
def self.columns
@columns ||= []
end
def self.column(name, sql_type = nil, default = nil, null = true)
type = "ActiveRecord::Type::#{sql_type.to_s.camelize}".constantize.new
columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, type, null, '')
end
def self.columns_hash
@columns_hash ||= Hash[columns.map { |column| [column.name, column] }]
end
def self.column_names
@column_names ||= columns.map { |column| column.name }
end
def self.column_defaults
@column_defaults ||= columns.map { |column| [column.name, nil] }.inject({}) { |m, e| m[e[0]] = e[1]; m }
end
# Override the save method to prevent exceptions.
def save(validate = true)
validate ? valid? : true
end
private
def self.load_schema!
columns_hash.each do |name, column|
self.define_attribute(
name,
column.sql_type_metadata,
default: column.default,
user_provided_default: false
)
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With