Rails:我可以使用两个嵌套的地图吗?

时间:2016-12-21 08:53:06

标签: ruby-on-rails

  def has_name? name
    results = auths.map do |auth|
                auth.role_groups.map do |role_group|
                  role_group.resources.any?{ |r| r.name == name}
                end
              end 
    results.any?
  end

这是用户模型中的一种方法 1位用户有很多身份证明 1 auth有许多role_groups
1 role_group有很多资源

我在那里使用了两张地图,但它没有返回我期望的结果。这是我第一次使用两个嵌套地图,我可以这样使用它吗?

2 个答案:

答案 0 :(得分:2)

你可以,但结果将有数组数组,并且它不被视为空。

[[]].any?
=> true

#flat_map可能会对您有所帮助

def has_name? name
  results = auths.flat_map do |auth|
    auth.role_groups.map do |role_group|
      role_group.resources.any?{ |r| r.name == name}
    end
  end 

  results.any?
end

或者您可以使用sql 将解决方案完全更改为更高效的解决方案(无需查看模型,不确定它是否可行)

auths.joins(role_groups: :resources).where(resources: { name: name }).exists?

答案 1 :(得分:0)

首先,您可以在authresources之间添加直接关系。 在Auth模型中: has_many: resources, through: role_groups

has-many-through关系也可以用于嵌套的has-many关系(就像你的情况一样)。在这里查看最后一个示例(文档,部分,段落关系):http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association

然后你可以这样做:

def has_name? name
  auths.includes(:resources).flat_map(&:resources).any? do |resource| 
    resource.name == name
  end
end