我想知道ActiveRecord::Associations::CollectionProxy
和ActiveRecord::AssociationRelation
之间的区别。
class Vehicle < ActiveRecord::Base
has_many :wheels
end
class Wheel < ActiveRecord::Base
belongs_to :vehicle
end
如果我这样做:
v = Vehicle.new
v.wheels # => #<ActiveRecord::Associations::CollectionProxy []>
v.wheels.all # => #<ActiveRecord::AssociationRelation []>
我不知道它们之间有什么区别以及为什么会这样实现?
答案 0 :(得分:16)
ActiveRecord::Relation
在转换为查询并执行之前是简单的查询对象,另一方面CollectionProxy
稍微复杂一些。
首先,你得到了关联扩展,你可能看到了这样的东西,假设一个有很多书的书店模型
class Store < ActiveRecord::Base
has_many :books do
def used
where(is_used: true)
end
end
end
这样您就可以使用类似于
的语法在商店中调用旧书Store.first.books.used
但这是最基本的用途,您可以使用在集合代理中公开的属性,owner
,reflection
和target
owner
提供对持有关联的父对象的引用
reflection
对象是ActiveRecord::Reflection::AssocciationReflection
的实例,包含关联的所有配置选项。
target
是关联集合对象(或has_one
和belongs_to
时的单个对象。)
使用这些方法,您可以在关联扩展中做一些条件,例如,如果我们有博客,我们会将所有已删除帖子的访问权限授予管理员用户(我知道的蹩脚示例)
Class Publisher < ActiveRecord::Base
has_many :posts do
def deleted
if owner.admin?
Post.where(deleted: true)
else
where(deleted: true)
end
end
end
end
您还可以访问另外两个reset
和reload
方法,第一个方法(reset
)清除缓存的关联对象,第二个方法(reload
)更常见,用于reset
,然后从数据库加载相关对象。
我希望这能解释如何让CollectionProxy
课程如此有用
答案 1 :(得分:9)
确定。差异非常简单。
基于您的示例的说明:
// trainingData is an int array with size 600x34
// labels is an int array with size 600, they're the labels corresponding to the trainingData rows
cv::Mat trainingDataMat(600, 34, CV_32FC1, trainingData);
cv::Mat labelsMat(600, 1, CV_32SC1, labels);
cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
cv::Ptr<cv::ml::TrainData> tempData = cv::ml::TrainData::create(trainingDataMat, cv::ml::ROW_SAMPLE, labelsMat);
svm->setType(cv::ml::SVM::C_SVC);
svm->setKernel(cv::ml::SVM::RBF);
svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, 100, 0.001));
// Assign the SVM parameters to the most accurate result
svm->trainAuto(tempData);
// Train the SVM
svm->train(trainingDataMat, cv::ml::ROW_SAMPLE, labelsMat);
// predictRow contains a row of data with 34 columns to predict against the SVM Model
cv::Mat sampleMat(1, 34, CV_32FC1, predictRow);
// Prediction
float response = svm->predict(sampleMat);
std::cout << response << std::endl;
中的关联代理具有:
v.wheels
中的对象为@owner; v
宏。来自docs:
Active Record中的关联代理是@owner之间的中间人 和@target。 在需要之前不会加载@target对象。
:has_many
这意味着,只要你调用@target对象上的任何方法(在我们的例子中包含v = Vehicle.new
v.wheels # we are not sending any methods to @target object (collection of wheels)
# => #<ActiveRecord::Associations::CollectionProxy []>
的集合),就会加载@target,它变为wheels
。
ActiveRecord_AssociationRelation