Reputation: 2198
My application configuration includes some values which need to be used in AR relationships. I'm aware this is an odd and potentially criminal thing to attempt, but I need to maintain the configuration as a textfile, and I honestly think I have a good case for a tableless model. Unfortunately I'm having trouble convincing AR (Rails 3.2) not to look for the table. My tableless model:
class Tableless < ActiveRecord::Base
def self.table_name
self.name.tableize
end
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
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
def self.descends_from_active_record?
return true
end
def persisted?
return false
end
def save( opts = {} )
options = { :validate => true }.merge(opts)
options[:validate] ? valid? : true
end
end
This is extended by the actual model:
class Stuff < Tableless
has_many :stuff_things
has_many :things, :through => :stuff_things
column :id, :integer
column :name, :string
column :value, :string
def initialize(attributes = {})
attributes.each do |name, value|
send("#{name}=", value)
end
end
end
This is all based on code found here on SO and elsewhere, but alas, I get SQLException: no such table: stuffs: Any clues any one?
Upvotes: 4
Views: 4446
Reputation: 3792
For Rails >= 4 you can also get support for validations, associations, and some callbacks (like after_initialize) by defining your tableless classes like this:
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
attr_accessor :id, :name, :value
has_many :stuff_things
has_many :things, :through => :stuff_things
end
Upvotes: 1
Reputation: 2861
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 (using ActiveModel opposed to ActiveRecord) to do it in Rails 3.x there is no support for association nor types.
Upvotes: 3