ruby-on-rails – 将数据库名称添加到表的Rails 3包括默认加载
资料来源:
> http://emphaticsolutions.com/2009/11/23/has_many_through_across_databases.html 我的项目正在转向拥有多个数据库(目前在同一台服务器上),我希望能够在这些数据库之间加入.为了做到这一点,我需要将数据库名称添加到表前缀,如下所示: class FirstBase < ActiveRecord::Base def self.table_name_prefix "DBNAME.t_" end establish_connection :firstdb end class User < FirstBase has_many :user_roles end class UserRole < FirstBase belongs_to :user end 添加表名称前缀似乎会影响包含在同一查询上的默认行为,即使在同一数据库中也是如此.考虑User.includes(:user_roles).first 没有表名前缀:
使用表名前缀:
换句话说,调用包含的默认行为已经从预加载更改为热负载. 有人知道为什么默认行为正在改变吗?必须有一些关于添加数据库名称,使Rails认为我们必须加载,但我不明白为什么.我也很惊讶地看到这一点,因为我想象的是添加数据库名称是不寻常的.我可以通过更改所有包含预加载来强制将其修复到我们的代码库中,但我想了解这里发生了什么.有没有办法改变默认行为? 解决方法
问题是table_name_prefix引入了一个句点.这混淆了试图确定它是否应该预加载或加载的逻辑.这是一个Rails 3错误,已在Rails 4中解决.如果您需要Rails 3中的特定行为,则需要明确指定预加载或eager_load,就像您在问题中所指出的那样.
在ActiveRecord::Relation,exec_queries调用eager_loading?来决定是否应该加载.这调用references_eager_loaded_tables?它使用tables_in_string尝试在SQL查询中查找不是连接表的一部分的表名: # ActiveRecord::Relation#references_eager_loaded_tables? (tables_in_string(to_sql) - joined_tables).any? tables_in_string方法有缺陷,因为它并不总是正确解析SQL.该代码可用于查看SQL查询中表名的内容: relation = User.includes(:user_roles) relation.send(:tables_in_string,relation.to_sql) 使用DBNAME.t_表名前缀,这将给出[“DBNAME”,“t_users”]作为表名,这是错误的.它应该给[“DBNAME.t_users”]. ActiveRecord query changing when a dot/period is in condition value记录了类似的问题.这导致ActiveRecord::Relation的变化在决定是预加载还是加载负载时,不再使用tables_in_string. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |