我可以将 ActiveRecord 关系与 Hstore 中的字段一起使用吗?
Can I use ActiveRecord relationships with fields from an Hstore?
我可以使用 hstore 散列中的字段通过活动记录 belongs_to 将一个模型与另一个模型联系起来吗?我会详细说明:
我有一个用户模型,它通过 STI 在其字段之一上根据权限被子类化为许多不同的其他用户模型:
class User < ActiveRecord::Base
self.inheritance_column = :role
#other definitions and validations
end
这是一个这样的子模型,nightclub_boss 模型,适用于我的应用程序的管理用户:
class NightclubBoss < User
belongs_to :nightclub #the boss record has a nightclub_id
has_one :rp_boss #rp_boss should have a nightclub_boss_id
has_one :captain #captain should have a nightclub_boss_id
end
这里的想法是使用以下信息扩展用户模型:
-User hierarchy (which user reports to who; get a list of who is under who as needed through the ORM)
-User origin (which user belongs to whatever other models are in the app)
所以我想出的办法是创建一个 hstore 字段,以避免拥有稀疏的用户 table 并避免产生大量的部分小 SQL tables在名为 "hierarchy" 的用户模型上,并将其映射到用户模型上的不同属性,当且仅当 相关用户需要存储层次结构信息(即,基于角色依赖;nightclub_boss 不应与我的应用程序中的其他模型具有相同的层次结构信息):
class AddHstore < ActiveRecord::Migration
def self.up
enable_extension "hstore"
end
def self.down
disable_extension "hstore"
end
end
class AddHierarchyToUser < ActiveRecord::Migration
def change
add_column :users, :hierarchy, :hstore
add_index :users, :hierarchy, using: :gin
end
end
运行
rake db:migrate
然后我将 hstore_accesssor 添加到我的模型中:
宝石文件:
gem "hstore_accessor"
用户模型:
class User < ActiveRecord::Base
self.inheritance_column = :role
hstore_accessor :hierarchy, nightclub_id: :integer
#other validations and definitions...
end
到目前为止一切都很好,使用硬编码数据进行测试:
[1] pry(main)> NightclubBoss.find(99)
NightclubBoss Load (1.3ms) SELECT "users".* FROM "users" WHERE "users"."role" IN ('NightclubBoss') AND "users"."id" = LIMIT 1 [["id", 99]]
=> #<NightclubBoss:0x000000070bbb00
id: 99,
#...all other fields...
role: "NightclubBoss",
hierarchy: {"nightclub_id"=>"1"}>
[2] pry(main)> NightclubBoss.find(99).nightclub_id
NightclubBoss Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."role" IN ('NightclubBoss') AND "users"."id" = LIMIT 1 [["id", 99]]
=> 1
所以您希望 rails 在调用 "NightclubBoss.nightclub" 时拉取绑定到该模型的相应 Nightclub.find(1),对吧?好吧,这不会发生:
[3] pry(main)> NightclubBoss.find(99).nightclub
NightclubBoss Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."role" IN ('NightclubBoss') AND "users"."id" = LIMIT 1 [["id", 99]]
=> nil
我已经尝试了各种方法来解决这个问题,但我还没有找到答案,有没有人可以提供帮助?
作为一种解决方法,我意识到我可以这样做:
Nightclub.find(NightclubBoss.find(99).nightclub_id)
而且我的查询很好。但我认为这可以改进,你希望能够做到 NightclubBoss.find(99).nightclub
我认为这也可能是一个非常糟糕的做法。如果有更好的方法来模拟我需要的那种信息,请告诉我,我会很感激你的建议。谢谢!
我一夜之间发现 Postgres 有一个名为 Jsonb 的类似数据类型,在将哈希存储在关系数据库的字段中的意义上,它也做与 hstore 类似的事情。
显然,由于 ActiveRecord 的限制,目前无法进行此匹配。它仅将匹配限制为关系数据库字段:
就个人而言,我对这个答案感到满意,所以如果没有人提供更多信息,我将关闭此线程,并且我将修改我的架构以不依赖于哈希字段。
想知道是否可以修补支持?
我可以使用 hstore 散列中的字段通过活动记录 belongs_to 将一个模型与另一个模型联系起来吗?我会详细说明:
我有一个用户模型,它通过 STI 在其字段之一上根据权限被子类化为许多不同的其他用户模型:
class User < ActiveRecord::Base
self.inheritance_column = :role
#other definitions and validations
end
这是一个这样的子模型,nightclub_boss 模型,适用于我的应用程序的管理用户:
class NightclubBoss < User
belongs_to :nightclub #the boss record has a nightclub_id
has_one :rp_boss #rp_boss should have a nightclub_boss_id
has_one :captain #captain should have a nightclub_boss_id
end
这里的想法是使用以下信息扩展用户模型:
-User hierarchy (which user reports to who; get a list of who is under who as needed through the ORM)
-User origin (which user belongs to whatever other models are in the app)
所以我想出的办法是创建一个 hstore 字段,以避免拥有稀疏的用户 table 并避免产生大量的部分小 SQL tables在名为 "hierarchy" 的用户模型上,并将其映射到用户模型上的不同属性,当且仅当 相关用户需要存储层次结构信息(即,基于角色依赖;nightclub_boss 不应与我的应用程序中的其他模型具有相同的层次结构信息):
class AddHstore < ActiveRecord::Migration
def self.up
enable_extension "hstore"
end
def self.down
disable_extension "hstore"
end
end
class AddHierarchyToUser < ActiveRecord::Migration
def change
add_column :users, :hierarchy, :hstore
add_index :users, :hierarchy, using: :gin
end
end
运行
rake db:migrate
然后我将 hstore_accesssor 添加到我的模型中:
宝石文件:
gem "hstore_accessor"
用户模型:
class User < ActiveRecord::Base
self.inheritance_column = :role
hstore_accessor :hierarchy, nightclub_id: :integer
#other validations and definitions...
end
到目前为止一切都很好,使用硬编码数据进行测试:
[1] pry(main)> NightclubBoss.find(99)
NightclubBoss Load (1.3ms) SELECT "users".* FROM "users" WHERE "users"."role" IN ('NightclubBoss') AND "users"."id" = LIMIT 1 [["id", 99]]
=> #<NightclubBoss:0x000000070bbb00
id: 99,
#...all other fields...
role: "NightclubBoss",
hierarchy: {"nightclub_id"=>"1"}>
[2] pry(main)> NightclubBoss.find(99).nightclub_id
NightclubBoss Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."role" IN ('NightclubBoss') AND "users"."id" = LIMIT 1 [["id", 99]]
=> 1
所以您希望 rails 在调用 "NightclubBoss.nightclub" 时拉取绑定到该模型的相应 Nightclub.find(1),对吧?好吧,这不会发生:
[3] pry(main)> NightclubBoss.find(99).nightclub
NightclubBoss Load (0.7ms) SELECT "users".* FROM "users" WHERE "users"."role" IN ('NightclubBoss') AND "users"."id" = LIMIT 1 [["id", 99]]
=> nil
我已经尝试了各种方法来解决这个问题,但我还没有找到答案,有没有人可以提供帮助?
作为一种解决方法,我意识到我可以这样做:
Nightclub.find(NightclubBoss.find(99).nightclub_id)
而且我的查询很好。但我认为这可以改进,你希望能够做到 NightclubBoss.find(99).nightclub
我认为这也可能是一个非常糟糕的做法。如果有更好的方法来模拟我需要的那种信息,请告诉我,我会很感激你的建议。谢谢!
我一夜之间发现 Postgres 有一个名为 Jsonb 的类似数据类型,在将哈希存储在关系数据库的字段中的意义上,它也做与 hstore 类似的事情。
显然,由于 ActiveRecord 的限制,目前无法进行此匹配。它仅将匹配限制为关系数据库字段:
就个人而言,我对这个答案感到满意,所以如果没有人提供更多信息,我将关闭此线程,并且我将修改我的架构以不依赖于哈希字段。
想知道是否可以修补支持?