轨道3.1中的无表模型

时间:2011-09-01 19:31:19

标签: ruby-on-rails-3.1

看起来this方法在rails 3.1中不再起作用了。那么,有人有一个可行的解决方案吗?

实际上,我发现了gist。它解决了railscast解决方案中出现columns_hashcolumn_defaults错误的问题,但当我尝试编写某个属性时,我总是出现ActiveRecord::ConnectionNotEstablished错误。

有什么想法吗?

6 个答案:

答案 0 :(得分:13)

Rails 3.1中最简单的无表格模型是:

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

ActiveModel :: Validations是可选的(仅在使用验证时)。此外,构造函数不是必需的(但非常需要)。

答案 1 :(得分:9)

对于Rails / ActiveRecord 5.0,您需要重新定义private def self.load_schema!以避免检查table_name。另外,请注意column方法(类型)的一点点破解。

这里是Rails 5.0 / ActiveRecord 5.0的Tableless模型的完整列表

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

答案 2 :(得分:7)

这种无表情的东西似乎越来越像一个黑客,但混合只是不一样的东西(不记得究竟什么现在不起作用,我几个月前处理过它,回到因为升级到3.1打破了它。 3.1.0rc4版本使用'columns_hash'方法覆盖,3.1.0也需要'column_defaults'覆盖。所以这是一个通过我的项目测试的版本。

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

  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
end

希望它适合你,

- 何塞

答案 3 :(得分:6)

您应该创建自己的模型类,并混合使用所需的ActiveModel部分(例如,验证)。 This blog post from Yehuda Katz有详细信息。

答案 4 :(得分:1)

对于Rails 3.2,有activerecord-tableless个宝石。它是创建无表格ActiveRecord模型的宝石,因此它支持验证,关联,类型。

当您在Rails 3.x中使用推荐的方法时,不支持关联或类型。

答案 5 :(得分:0)

和对于Rails 3.2,RUBY的版本应该是首选的1.9.3以避免不兼容。