通过关联订购 has_many
Ordering a has_many through association
我想急切地加载一个 ActiveRecord 集合及其关联的集合:
class BodyPort < ActiveRecord::Base
has_many :body_port_dimensions
has_many :dimensions, through: :body_port_dimensions, order: 'dimensions.value'
scope :ordered, order('name ASC')
end
class BodyPortDimension < ActiveRecord::Base
belongs_to :dimension
end
class Dimension < ActiveRecord::Base
end
急切加载协会:
BodyPort.includes(:dimensions).ordered
生成 SQL:
SELECT `body_ports`.*
FROM `body_ports`
ORDER BY name ASC
SELECT `body_port_dimensions`.*
FROM `body_port_dimensions`
WHERE `body_port_dimensions`.`body_port_id` IN (3, 5, 7, 6, 2, 8, 9, 4, 1)
ORDER BY dimensions.value
引发 SQL 异常:
=> ActiveRecord::StatementInvalid: Mysql2::Error:
Unknown column 'dimensions.value' in 'order clause':
SELECT `body_port_dimensions`.*
FROM `body_port_dimensions`
WHERE `body_port_dimensions`.`body_port_id` IN (3, 5, 7, 6, 2, 8, 9, 4, 1)
ORDER BY dimensions.value
如何生成内部联接 SQL 改为:
SELECT `dimensions`.*
FROM `dimensions`
INNER JOIN `body_port_dimensions`
ON `dimensions`.`id` = `body_port_dimensions`.`dimension_id`
WHERE `body_port_dimensions`.`body_port_id` IN (3, 5, 7, 6, 2, 8, 9, 4, 1)
ORDER BY dimensions.value
在 edsinclair patch 之后:
config/initializers/extensions.rb:
require "active_record_has_many_through_patch"
lib/active_record_has_many_through_patch.rb:
module ActiveRecordHasManyThroughPatch
def self.through_options
through_options = {}
if options[:source_type]
through_options[:conditions] = { reflection.foreign_type => options[:source_type] }
else
if options[:conditions]
through_options[:include] = options[:include] || options[:source]
through_options[:conditions] = options[:conditions]
end
if options.has_key?(:order)
through_options[:order] = options[:order]
if options.has_key?(:through) && options.has_key?(:source)
through_options[:include] = options[:source]
end
end
end
through_options
end
end
我想急切地加载一个 ActiveRecord 集合及其关联的集合:
class BodyPort < ActiveRecord::Base
has_many :body_port_dimensions
has_many :dimensions, through: :body_port_dimensions, order: 'dimensions.value'
scope :ordered, order('name ASC')
end
class BodyPortDimension < ActiveRecord::Base
belongs_to :dimension
end
class Dimension < ActiveRecord::Base
end
急切加载协会:
BodyPort.includes(:dimensions).ordered
生成 SQL:
SELECT `body_ports`.*
FROM `body_ports`
ORDER BY name ASC
SELECT `body_port_dimensions`.*
FROM `body_port_dimensions`
WHERE `body_port_dimensions`.`body_port_id` IN (3, 5, 7, 6, 2, 8, 9, 4, 1)
ORDER BY dimensions.value
引发 SQL 异常:
=> ActiveRecord::StatementInvalid: Mysql2::Error:
Unknown column 'dimensions.value' in 'order clause':
SELECT `body_port_dimensions`.*
FROM `body_port_dimensions`
WHERE `body_port_dimensions`.`body_port_id` IN (3, 5, 7, 6, 2, 8, 9, 4, 1)
ORDER BY dimensions.value
如何生成内部联接 SQL 改为:
SELECT `dimensions`.*
FROM `dimensions`
INNER JOIN `body_port_dimensions`
ON `dimensions`.`id` = `body_port_dimensions`.`dimension_id`
WHERE `body_port_dimensions`.`body_port_id` IN (3, 5, 7, 6, 2, 8, 9, 4, 1)
ORDER BY dimensions.value
在 edsinclair patch 之后:
config/initializers/extensions.rb:
require "active_record_has_many_through_patch"
lib/active_record_has_many_through_patch.rb:
module ActiveRecordHasManyThroughPatch
def self.through_options
through_options = {}
if options[:source_type]
through_options[:conditions] = { reflection.foreign_type => options[:source_type] }
else
if options[:conditions]
through_options[:include] = options[:include] || options[:source]
through_options[:conditions] = options[:conditions]
end
if options.has_key?(:order)
through_options[:order] = options[:order]
if options.has_key?(:through) && options.has_key?(:source)
through_options[:include] = options[:source]
end
end
end
through_options
end
end