我基于has_one
或has_many
关系动态构建查询。所以,我最终可以得到一个对象或CollectionProxy。如何根据此结果测试查询是使用has_one
还是has_many
关系?
我想过检查类型,但CollectionProxy的类型是相关模型类型的子类。
此动态查询涉及调用对象的属性,该属性可以是has_one
或has_many
关系。类似的东西:
class User < ActiveRecord::Base
has_one :profile
has_many :names
user = User.new
attr = 'profile' # or 'names'
user.send(attr) # I want to check whether this is a result of which of the two relations
答案 0 :(得分:4)
您可以使用Active Record的reflection:
User.reflect_on_association(:profile)
#=> #<ActiveRecord::Reflection::HasOneReflection:0x007fd2b76705c0 ...>
User.reflect_on_association(:names)
#=> #<ActiveRecord::Reflection::HasManyReflection:0x007fd2b767de78 ...>
在case
声明中:
klass = User
attr = :profile
case klass.reflect_on_association(attr)
when ActiveRecord::Reflection::HasOneReflection
# ...
when ActiveRecord::Reflection::HasManyReflection
# ...
end
这基于模型中的关联声明(user.rb
),即无需访问数据库。
答案 1 :(得分:2)
您可以实际检查结果的类型。您只需检查它是ActiveRecord :: Base还是ActiveRecord :: Associations :: CollectionProxy。
按照你的例子:
class User < ActiveRecord::Base
has_one :profile
has_many :names
user = User.new
attr = 'profile'
user.send(attr).is_a? ActiveRecord::Base # true
user.send(attr).is_a? ActiveRecord::Associations::CollectionProxy # false
attr = 'names'
user.send(attr).is_a? ActiveRecord::Base # false
user.send(attr).is_a? ActiveRecord::Associations::CollectionProxy # true
这是在Rails 4.1.4上测试的,但是从Rails 3开始,这些类显然是相同的。
答案 2 :(得分:0)
考虑像这样使用dst
:
try
这样post.try(:owner)
关系将返回has_one
而owner
则不会。
在某些情况下,它可能是不确定的,但对大多数情况来说应该足够了。
has_many
只是一个例子:
owner
如果上课class Post
has_one :owner
class Owner
belongs_to :post
post = Post.create ...
post.try(:owner)
owner
,则返回Post
;如果上课has_one :owner
nil
Post
对于您的示例: has_many :owners