为什么 ActiveRecord::Store.store_acessor 在查询时不反映结果 SQL

Thi*_*niz 1 ruby activerecord ruby-on-rails hstore

考虑这个类:

class UsersMigration < ActiveRecord::Migration[5.2]
  def change
    create_table(:users) do |t|
      t.hstore  :settings
    end
  end
end

class User < ActiveRecord::Base
  store_accessor :settings, :privileges, :colors
end
Run Code Online (Sandbox Code Playgroud)

执行此查询时:

User.where(privileges: 'Admin')
Run Code Online (Sandbox Code Playgroud)

它会导致此错误: ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: column users.privileges does not exist) 并且是正确的,因为该列实际上是设置

为了进行查询,我们必须这样做:

User.where("settings->'privileges' = 'Admin'")
Run Code Online (Sandbox Code Playgroud)

如果模型已经显式序列化到 hstore 列,为什么第一个查询不会产生以下 SQL:

SELECT  "user".* FROM "users" WHERE (settings->'privileges' = 'Admin')
Run Code Online (Sandbox Code Playgroud)

max*_*max 5

ActiveRecord 并不是为了真正关心 hstore、json 或数组列的内容而构建的。AR 是围绕包含表和列的关系模型构建的。表中的列对应于模型中的属性。

Hstore、json 和数组类型是相对较新的数据库功能,但并不一定不是多语言的。每个数据库的实现都不同。在 ActiveRecord 中,对这些列的支持实际上是由数据库驱动程序而不是框架本身提供的。

store_accessor只需创建一个 getter/setter 并为模型中的属性设置脏跟踪。它不会“明确告诉”AR hstore 列中存在特定键 - 请记住 AR 不关心 hstore 列的内容。

事实上,我想说,如果您以这种方式使用它,那么这是一个非常明显的迹象,表明您已经成为JSON/hstore 反模式的受害者。