【问题标题】:Tableless model with ActiveRecord associations in Rails 3.2Rails 3.2 中具有 ActiveRecord 关联的无表模型
【发布时间】:2012-05-23 23:31:09
【问题描述】:

我的应用程序配置包含一些需要在 AR 关系中使用的值。我知道这是一件奇怪且可能犯罪的事情,但我需要将配置维护为文本文件,老实说,我认为我有一个很好的无表格模型案例。不幸的是,我无法说服 AR(Rails 3.2)不要寻找表格。我的无表模型:

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

这是由实际模型扩展的:

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

这一切都基于找到here on SOelsewhere 的代码,但是我得到SQLException: no such table: stuffs: 任何线索吗?

【问题讨论】:

  • 我对此知之甚少,无法提供答案,但是关于这个主题有一个 Railscast,虽然有点老了railscasts.com/episodes/193-tableless-model
  • 谢谢!看了这一集,它基本上概述了我正在使用的相同方法。 Rails 3 似乎发生了一些变化,影响了欺骗 AR 表的能力——或者我错过了其他东西!
  • 我知道有一个叫做 active_attr 的 gem,它也提供了一些没有表的模型行为,可能值得研究
  • 再次感谢,但该 gem 似乎不包含关联。
  • 您可以在初始化程序中将数据加载到数据库中吗?没有理由不能在两个地方拥有数据。

标签: ruby-on-rails activerecord model


【解决方案1】:

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

当您在 Rails 3.x 中使用推荐的方式(使用 ActiveModel 而不是 ActiveRecord)时,不支持关联或类型。

【讨论】:

  • 有趣的是我只是在 Github 上找到它 :) 我不太了解第二段 :( 你知道它是否支持 ActiveRecord 的持久工作流吗?我不确定我是否不会切断我的绳索到创建和更新方法......
  • 取决于你所说的坚持工作流的意思。 gem 丢弃了 ActiveRecord 的持久性部分......即它不会持久化。
【解决方案2】:

对于 Rails >= 4,您还可以通过像这样定义无表类来支持验证、关联和一些回调(如 after_initialize):

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

【讨论】:

  • Eric,列类方法是绝对必要的吗?什么时候会被调用?我在一个带有几个表关联的表表单模型中使用它,并且只有调用有效的新/创建操作?。
猜你喜欢
  • 1970-01-01
  • 2013-07-01
  • 2013-04-29
  • 2017-01-25
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多