Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 通过Rails关系选择模型?_Sql_Ruby On Rails_Ruby_Ruby On Rails 4 - Fatal编程技术网

Sql 通过Rails关系选择模型?

Sql 通过Rails关系选择模型?,sql,ruby-on-rails,ruby,ruby-on-rails-4,Sql,Ruby On Rails,Ruby,Ruby On Rails 4,我有以下(简化)模型: 我想选择public为true的所有地址,以及用户可以通过组访问的所有地址 我认为这是一个大致如下的问题: Address.where(public: TRUE).joins(:group_member) 我在附近吗 我正在使用Rails 4和PostgreSQL作为我的数据库,如果它对任何人都有帮助的话。我认为这会起作用: Address.joins(group_member: :group).where(is_public: true, groups: {user_

我有以下(简化)模型:

我想选择
public
为true的所有地址,以及用户可以通过组访问的所有地址

我认为这是一个大致如下的问题:

Address.where(public: TRUE).joins(:group_member)
我在附近吗


我正在使用Rails 4和PostgreSQL作为我的数据库,如果它对任何人都有帮助的话。

我认为这会起作用:

Address.joins(group_member: :group).where(is_public: true, groups: {user_id: 12345})
让我们来分析一下

首先,我们调用
地址
模型,b/c,这是我们想要返回的

.joins(:group\u member)
将通过
地址
有一个:group\u member
关系将地址加入到
组成员

然而,我们实际上想更进一步,加入与
组成员连接的
组,因此我们使用嵌套的连接,这就是为什么看起来像这样
加入(组成员::组)
来表示我们加入地址->组成员,然后是组成员->组

接下来是where子句。我们需要两个条件:

  • 仅限公共地址,在地址上以列表示,因此我们添加以下内容:
    .where(is\u public:true)
  • 我们只希望特定用户与组(及其组成员和地址)连接。为此,我们需要添加一个嵌套的where子句,如so
    groups:{user\u id:12345}
  • 将这些因素结合起来的结果是:

    where(是公共的:true,组:{user\u id:12345})

    总之,上面的代码行应该得到您想要的结果。

    试试下面的方法——它不是一个单一的查询,但我认为它比一个带有大联接表的单一查询要好:

    public_addresses = Address.where(is_public: true)
    # =>  get all public addresses
    
    user_addresses = current_user.groups.includes(:group_members => :address).
                    # includes is to eager load records to avoid N+1 queries
                    flat_map{|g| g.group_members.map(&:address)}
                    # inner block returns array of addresses for each group
                    # flat_map converts the array of arrays to single level 
    # => get all addresses associated with the user
    
    
    all_addresses = (public_addresses + user_addresses).uniq
    # =>  remove duplicates
    
    要加快查询速度,请为较慢的查询添加索引。例如

       add_index :groups, :user_id
       # this speeds up finding groups for a given user
    
       add_index :group_members, :group_id
       # this speeds up finding group_members for a given group
    
       add_index :addresses, :group_member_id
       # this speeds up finding addresses for a given group_member
    
    其他选项是使用
    join
    表获取
    user\u地址

       user_addresses = Address.joins(group_member: group).where(groups: {user_id: current_user.id} )
    

    你是说地址而不是型号吗?
    哦,是的,谢谢你的注意!)public在ruby中是一个保留字,您可能想使用类似is_public的属性。谢谢@AndrewKuklewicz,这可能会让我非常痛苦。您是否正在尝试访问特定用户或任何用户的
    地址?“在地址上找不到名为“groups”的关联”是我得到的,所以你需要添加关系的另一端-地址属于:组成员但地址没有任何组。你能解释一下你的代码吗?啊,没有嵌套连接,编辑。还有,看看这个例子:那就没有意义了。如果GroupMember有一个地址,则地址必须有一个group member id。如果GroupMember属于地址,则GroupMember上应该有一个address id。所以,用GroupMember替换供应商,用Address替换帐户-明白我的意思吗?您的密钥或关系有误。“找不到关联:模式用户中的组成员”您是否尝试了
    用户
    用户
    ?已更新,以便更清楚地显示…
    当前用户
    是已登录的用户in@DanAndreasson请看文档…这需要在db迁移中进行。ohhh..这方面有很多文章,例如,看到这个了吗
       user_addresses = Address.joins(group_member: group).where(groups: {user_id: current_user.id} )