如何在rails中创建同一模型之间的深层关系?

时间:2012-05-24 21:15:48

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-3.1

基于本教程

自我参照协会

http://railscasts.com/episodes/163-self-referential-association

我们可以看到我们添加的朋友,也可以转到用户的个人资料,并使用此代码查看他的朋友:

  <% for friendship in @user.friendships %>
     <%= friendship.friend.username %>
  <% end %>

  <% for user in @user.inverse_friends %>
    <li><%= user.username %></li>
  <% end %>

但是我怎么能更深入地看到朋友的朋友,我的意思是如果你去看一个用户的个人资料你可以通过朋友看到他的边缘,这是1级,我怎么能看到朋友的他的朋友在同一页面,是否可能?。

我给了这个例子来自railscasts导致我的app工作原理相同,我需要更深入的因为我需要制作jqueryChart并且我需要更多的分支,为了拥有更多的分支我需要得到朋友之间的关系一个用户和朋友的朋友(男人,很难)。 非常感谢你。

                                         User
level 1         user.friend 1            user.friend 2                user.friend 3
level 2    friend 4 of user.friend 1     friend 1 of user.friend 2
level 3    friend 5 of friend 4

所以这可能会更清楚,我怎样才能至少在同一个用户页面上进入leve 2?

2 个答案:

答案 0 :(得分:3)

首先,您可以将此添加到您的用户模型,以便更轻松地吸引所有朋友

has_many :friends, :through => friendships

所以你现在可以做到

<% for friend in @user.friends %>
  <%=friend.username %>
<% end %>

而不是

<% for friendship in @user.friendships %>
  <%= friendship.friend.username %>
<% end %>

并使用每种方法

<% @user.friends.each do |friend| %>
  <%=friend.username %>
<% end %>

所以,我认为这解决了你的问题,但对于制作而言,这不是一个非常好的解决方案。

<% @user.friends.each do |friend| %>
  <%=friend.username %>
  <%= friend.friends.each do |fof| %>
    <ul>
      <li><%= fof.username %></li>
    </ul>
  <% end %>
<% end %>

那么,为什么会这样呢?因为朋友实际上也是来自User模型,并且拥有与@user相同的方法,所以每个朋友都有朋友方法就可以了。 你可以把所有的筑巢都放在一边。在那个截屏视频中,他使用user.friendships而不是user.friends只是因为他需要friendship_id来制作link_to来删除友谊。因此,如果您只想显示用户名,可以直接使用user.friends。

为什么这可能是一种不好的做法?因为您为每个朋友创建了一个新的数据库查询,所以您必须得到他们的朋友。但也许它实际上并没有那么糟糕,如果有一些缓存,那些查询应该比实际上的连接更好,因为连接查询对于当前用户是唯一的,并且它的缓存将仅从他使用,如果每个用户都有一个单独的查询,然后这些缓存的查询将被多次使用,因为所有朋友都会看到其他朋友的朋友。

答案 1 :(得分:1)

这实际上是一个非常深刻的问题,做正确的事情需要付出一些努力。结帐:

Graph Edges Rails