How to create ActiveRecord tableless Model in Rails 3

泪湿孤枕 提交于 2019-11-30 06:50:06
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
stephenmurdoch

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.

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

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.

Just remove:

class_inheritable_accessor :columns

And it should work, even with associations just like a model with a table.

Just for anyone still struggling with this. For rails 2.x.x

class TestImp < ActiveRecord::Base

  def self.columns
    @columns ||= []
  end
end

For rails 3.1.x you can either include ActiveModel (as explained by @ducktyped) without inheriting from ActiveRecord or If you do need to inherit from ActiveRecord::Base due to some reason then the above with one other addition:

class TestImp < ActiveRecord::Base

  def attributes_from_column_definition
    []
  end

  def self.columns
    @columns ||= []
  end
end

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!