How to create ActiveRecord tableless Model in Rails 3

北慕城南 提交于 2019-12-18 12:15:22

问题


I am trying to create a Active Record tableless Model. My user.rb looks like this

class User < ActiveRecord::Base

  class_inheritable_accessor :columns

  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


  column :name, :text
  column :exception, :text
  serialize :exception      
end

When creating the new object in controller

@user = User.new

I am getting the error

Mysql2::Error: Table 'Sampledb.users' doesn't exist: SHOW FIELDS FROM users


回答1:


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



回答2:


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.




回答3:


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



回答4:


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.




回答5:


Just remove:

class_inheritable_accessor :columns

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




回答6:


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



回答7:


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.



来源:https://stackoverflow.com/questions/9123858/how-to-create-activerecord-tableless-model-in-rails-3

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