Mar*_*van 3 ruby ruby-on-rails
def follows(follower, followed)
follow = Follows.where("follower = ? AND followed = ?", follower, followed)
if follow
true
else
false
end
end
Run Code Online (Sandbox Code Playgroud)
这是我的观看代码:
<% if current_user.id == @user.id%>
<p>This is you!</p>
<% else %>
<% if follows(current_user.id, @user.id)%>
<p>You already follow <%= @user.username %>
<% else %>
<p><%= link_to "Follow!", follow_path(@user.id) %></p>
<% end %>
<% end %>
Run Code Online (Sandbox Code Playgroud)
我想检查用户是否跟随另一个用户,所以写了这个.它发生在两个用户ID,并查询数据库,并应在发现匹配,否则为false返回true.但它总是回归真实.为什么是这样?
让我们先从一些风格和设计问题开始,然后以实际答案结束:
模型按惯例是单数的.否则只会让你工作更多.在这种情况下,我建议Following作为一个合适的名称,如"用户有很多以下".
外键应该以_id.否则只会让你工作更多.所以follower_id和followed_id.
你的if语句是多余的,一旦条件做对了就可以安全地删除.在红宝石中,在条件语境中,我们更关心事物是否评价为真/假,而不是它们是字面true还是字面false.这意味着除了nil或false将"truthy" 以外的任何东西.
事实上,你的方法完全取决于User对象已知的信息,这表明最好将它挂在那些对象之外current_user.follows? other_user.
您正在复制已使用关联提供给您的行为.
最后,考虑到所有这些因素,答案是:
class User < ActiveRecord::Base
has_many :followings, :class_name => 'Following', :foreign_key => 'followed_id'
has_many :followers, :through => 'followings'
def follows?(other)
other.followed_by? self
end
def followed_by?(other)
followers.include? other
end
end
Run Code Online (Sandbox Code Playgroud)
注意:这里使用的followed_by?方法是使用双重调度,防止Demeter的(次要)法则违反一个用户直接了解另一个用户的关注者的状态.相反,第一个用户对象向第二个用户对象询问一个直接问题("你跟着我吗?")并将结果基于答案.(它本身也可能是一种有用的方法.)
| 归档时间: |
|
| 查看次数: |
1165 次 |
| 最近记录: |