ruby-on-rails - 此代码中引用的模型关联行的 3.1 版本在哪里
问题描述
好的...所以,我继承了我最近升级到 Rails 3.1 的旧 Rails 2.3.14 应用程序(是的,我知道 6.x 是最新的,但首先是婴儿步骤。)
我在原始代码库中发现了一些看起来像是已经完成的元编程。三个类已被覆盖。只有最后一个...class AssociationReflection
可以在 Rails 3.1 Activerecord 中引用。另外两个已经被重构为其他东西,在 Rails 3.1 Activerecord 的其他地方。
仅供参考:此代码中发生的情况是 alias_method 被用于允许使用这些修改后的副本覆盖原始代码。
...我已经标记了从原始更改的每一行,##ORIGINALY:
总共大约有 7 行,其中 6 行我需要重构。
rails_fix.rb
# NOTE:
# This makes brittle code. the instant the original methods aliased here no
# longer exist on the rails 3.1 activeRecord side..this code will break..and
# the app will break. Which is why the new programmer(me) has to fix it.
# This instantly coupled the code to a specific version of rails.
#
# NOTE: this is meta programming ... see SO post
# https://stackoverflow.com/questions/3695839/ruby-on-rails-alias-method-chain-what-exactly-does-it-do
module ActiveRecord
module Associations
module ClassMethods
class JoinDependency
class JoinAssociation
def association_join_with_fix
connection = reflection.active_record.connection
join = case reflection.macro
when :has_and_belongs_to_many
" #{join_type} %s ON %s.%s = %s.%s " % [
table_alias_for(options[:join_table], aliased_join_table_name),
connection.quote_table_name(aliased_join_table_name),
options[:foreign_key] || reflection.active_record.to_s.foreign_key,
connection.quote_table_name(parent.aliased_table_name),
reflection.active_record.primary_key] +
" #{join_type} %s ON %s.%s = %s.%s " % [
table_name_and_alias,
connection.quote_table_name(aliased_table_name),
klass.primary_key,
connection.quote_table_name(aliased_join_table_name),
options[:association_foreign_key] || klass.to_s.foreign_key
]
when :has_many, :has_one
case
when reflection.options[:through]
through_conditions = through_reflection.options[:conditions] ? "AND #{interpolate_sql(sanitize_sql(through_reflection.options[:conditions]))}" : ''
jt_foreign_key = jt_as_extra = jt_source_extra = jt_sti_extra = nil
first_key = second_key = as_extra = nil
if through_reflection.options[:as] # has_many :through against a polymorphic join
jt_foreign_key = through_reflection.options[:as].to_s + '_id'
jt_as_extra = " AND %s.%s = %s" % [
connection.quote_table_name(aliased_join_table_name),
connection.quote_column_name(through_reflection.options[:as].to_s + '_type'),
klass.quote_value(parent.active_record.base_class.name)
]
else
jt_foreign_key = through_reflection.primary_key_name
end
case source_reflection.macro
when :has_many
if source_reflection.options[:as]
first_key = "#{source_reflection.options[:as]}_id"
second_key = options[:foreign_key] || primary_key
as_extra = " AND %s.%s = %s" % [
connection.quote_table_name(aliased_table_name),
connection.quote_column_name("#{source_reflection.options[:as]}_type"),
klass.quote_value(source_reflection.active_record.base_class.name)
]
else
first_key = source_reflection.association_foreign_key ##ORIGINALY: through_reflection.klass.base_class.to_s.foreign_key
second_key = source_reflection.primary_key_name ##ORIGINALY: options[:foreign_key] || primary_key
end
unless through_reflection.klass.descends_from_active_record?
jt_sti_extra = " AND %s.%s = %s" % [
connection.quote_table_name(aliased_join_table_name),
connection.quote_column_name(through_reflection.active_record.inheritance_column),
through_reflection.klass.quote_value(through_reflection.klass.sti_name)]
end
when :belongs_to
first_key = primary_key
if reflection.options[:source_type]
second_key = source_reflection.association_foreign_key
jt_source_extra = " AND %s.%s = %s" % [
connection.quote_table_name(aliased_join_table_name),
connection.quote_column_name(reflection.source_reflection.options[:foreign_type]),
klass.quote_value(reflection.options[:source_type])
]
else
second_key = source_reflection.primary_key_name
end
end
" #{join_type} %s ON (%s.%s = %s.%s%s%s%s) " % [
table_alias_for(through_reflection.klass.table_name, aliased_join_table_name),
connection.quote_table_name(aliased_join_table_name), ##ORIGINALY: connection.quote_table_name(parent.aliased_table_name),
connection.quote_column_name(parent.primary_key),
connection.quote_table_name(parent.aliased_table_name),##ORIGINALY: connection.quote_table_name(aliased_join_table_name),
connection.quote_column_name(jt_foreign_key),
jt_as_extra, jt_source_extra, jt_sti_extra
] +
" #{join_type} %s ON (%s.%s = %s.%s%s) " % [
table_name_and_alias,
connection.quote_table_name(aliased_table_name),
connection.quote_column_name(first_key),
connection.quote_table_name(aliased_join_table_name),
connection.quote_column_name(second_key),
as_extra
]
when reflection.options[:as] && [:has_many, :has_one].include?(reflection.macro)
" #{join_type} %s ON %s.%s = %s.%s AND %s.%s = %s" % [
table_name_and_alias,
connection.quote_table_name(aliased_table_name),
"#{reflection.options[:as]}_id",
connection.quote_table_name(parent.aliased_table_name),
parent.primary_key,
connection.quote_table_name(aliased_table_name),
"#{reflection.options[:as]}_type",
klass.quote_value(parent.active_record.base_class.name)
]
else
foreign_key = options[:foreign_key] || reflection.active_record.name.foreign_key
" #{join_type} %s ON %s.%s = %s.%s " % [
table_name_and_alias,
aliased_table_name,
foreign_key,
parent.aliased_table_name,
reflection.options[:primary_key] || parent.primary_key
]
end
when :belongs_to
" #{join_type} %s ON %s.%s = %s.%s " % [
table_name_and_alias,
connection.quote_table_name(aliased_table_name),
reflection.klass.primary_key, ##ORIGINALY: reflection.options[:primary_key] || reflection.klass.primary_key,
connection.quote_table_name(parent.aliased_table_name),
options[:foreign_key] || reflection.primary_key_name
]
else
""
end || ''
join << %(AND %s) % [
klass.send(:type_condition, aliased_table_name)] unless klass.descends_from_active_record?
[through_reflection, reflection].each do |ref|
join << "AND #{interpolate_sql(sanitize_sql(ref.options[:conditions], aliased_table_name))} " if ref && ref.options[:conditions]
end
join
end
alias_method_chain :association_join, :fix
end
end
end
end
end
module ActiveRecord
module Associations
class HasManyThroughAssociation
def construct_joins_with_fix(custom_joins = nil)
polymorphic_join = nil
if @reflection.source_reflection.macro == :belongs_to
reflection_primary_key = @reflection.klass.primary_key
source_primary_key = @reflection.source_reflection.primary_key_name
if @reflection.options[:source_type]
polymorphic_join = "AND %s.%s = %s" % [
@reflection.through_reflection.quoted_table_name, "#{@reflection.source_reflection.options[:foreign_type]}",
@owner.class.quote_value(@reflection.options[:source_type])
]
end
else
reflection_primary_key = @reflection.source_reflection.primary_key_name
source_primary_key = @reflection.source_reflection.association_foreign_key ##ORIGINALY: @reflection.through_reflection.klass.primary_key
if @reflection.source_reflection.options[:as]
polymorphic_join = "AND %s.%s = %s" % [
@reflection.quoted_table_name, "#{@reflection.source_reflection.options[:as]}_type",
@owner.class.quote_value(@reflection.through_reflection.klass.name)
]
end
end
"INNER JOIN %s ON %s.%s = %s.%s %s #{@reflection.options[:joins]} #{custom_joins}" % [
@reflection.through_reflection.quoted_table_name,
@reflection.quoted_table_name, reflection_primary_key,
@reflection.through_reflection.quoted_table_name, source_primary_key,
polymorphic_join
]
end
alias_method_chain :construct_joins, :fix
end
end
end
module ActiveRecord
module Reflection
class AssociationReflection
def association_foreign_key_with_fix
@association_foreign_key ||= @options[:primary_key] || class_name.foreign_key ##ORIGINALY: @association_foreign_key ||= @options[:association_foreign_key] || class_name.foreign_key
end
alias_method_chain :association_foreign_key, :fix
end
end
end
注意:这是元编程......请参阅 Ruby on Rails 的 SO 帖子:alias_method_chain,它到底是做什么的?
所以问题是:有什么...
module ActiveRecord
module Associations
class HasManyThroughAssociation
def construct_joins
...和...
module ActiveRecord
module Associations
module ClassMethods
class JoinDependency
class JoinAssociation
def association_join
...被重构为标记为 "#ORIGINALY:" 的 6 行的等价物是什么?
我想我可能必须rails_fix.rb
使用 Rails 3.1 版本的 ActiveRecord 关联方法构建另一个版本。但我不知道当前代码是什么/在哪里。
我希望这个问题是有道理的。感谢您的时间。
解决方案
推荐阅读
- flutter - flutter SkCanvas::Flush 执行太慢
- go - 如何阅读 Windows 事件日志
- javascript - 将 Promise.all() 链接到 ID 数组
- python - 从查询集 django 中获取不同的值?
- azure - 如何在 Azure Applications Insights 中使用新列而不是跟踪和请求等创建自定义日志?
- c++ - 如何向根节点发送回复,同时向子节点发送消息?
- c# - 如何使用存储过程使用 3 层架构并将它们称为标志以在 crud 中实现?
- javascript - javascript - 验证对象内的嵌套键
- sql - 在Oracle中以逗号分隔的列中获取唯一长度的可用数据
- firebase - 如何使用 Firestore 数据库中的更改自动重建 next.js 应用程序?