Ruby on rails 即使证明错误,Helper方法也始终返回true

Ruby on rails 即使证明错误,Helper方法也始终返回true,ruby-on-rails,ruby,Ruby On Rails,Ruby,我在rails 4中使用了以下helper方法 def is_blog_owner?(blog_id) if current_user && blog_id blog = Blog.find_by(id: blog_id) roles = current_user.roles_for_blog(blog) roles.each do |role| if role.role == 'Blog-Owner'

我在rails 4中使用了以下helper方法

  def is_blog_owner?(blog_id)
    if current_user && blog_id
      blog = Blog.find_by(id: blog_id)
      roles = current_user.roles_for_blog(blog)
      roles.each do |role|
        if role.role == 'Blog-Owner'
          true
        end
      end
    end
  end
它有一个问题,如果当前用户的角色为零,它似乎总是返回true

当前的工作方式是,如果当前用户具有特定博客的博客所有者角色,则返回true

因此,如果我访问(作为用户id 1)
users/1/blogs/2
,我将在
show.html.erb
中看到编辑和删除,如下所示。但是,如果我以用户id 2的身份注销和登录并访问
users/1/blogs/2
我仍然会看到编辑和删除。我不应该这样

所以我抛出了一个
绑定。在
角色
设置并在用户id 1的blog id 2上找到用户id 2的
角色
后,pry
为零。这意味着我不应该看到编辑和删除按钮,但我确实看到了。。。怎么回事

<h2><%=@blog.title%> Profile</h2>

<p class="text-muted">
    Welcome to your blog porfile page. Here you can manage the blog. You can edit or
    delete the specific blog.
</p>

<% if is_blog_owner?(params[:id]) %>

  <hr>
  <h3>Action</h3>
  <p class="text-muted">You can currently do the following actions: </p>

  <%= link_to "Edit", edit_user_blog_path(current_user.id, @blog.id), :class => 'btn btn-success' %> |
  <%= link_to "Delete", user_blog_path(current_user.id, @blog.id),
  data: { confirm: "This is permenent. Are you sure?" },
  :method => :delete,
  :class => 'btn btn-danger'%>

<% end %>
Profile

欢迎来到你的博客文件页面。在这里你可以管理博客。您可以编辑或 删除特定的博客。


行动

您当前可以执行以下操作:

“btn btn成功”%>| :删除, :class=>“btn btn危险”%>

我应该说我做了一个
这个构造对你来说是个问题:

  roles.each do |role|
    if role.role == 'Blog-Owner'
      true
    end
  end
它返回
角色
的值,该值可能是一个
数组
,因此始终为真值。块内的独立
true
不会返回,这不是
的工作方式。每个
都是这样工作的。通常使用
.each
来处理数组中要更改的项,或者基于每个项进行输出,或者基于每个项执行一些副作用。返回值始终是
数组
对象,与块内的操作无关

相反,您可以使用与您的意图相符的方法
.any?

  roles.any? do |role|
    role.role == 'Blog-Owner'
  end

您的问题是,
roles.each…
返回调用它的枚举数-因此本质上您的方法总是返回
roles

要对其进行排序,请将其更改为:

def is_blog_owner?(blog_id)
  if current_user && blog_id
    blog = Blog.find_by(id: blog_id)
    roles = current_user.roles_for_blog(blog)
    roles.each do |role|
      if role.role == 'Blog-Owner'
        return true
      end
    end
  end
  return false
end
但最好是重新编写它,以便更清楚地了解它在做什么。所以它检查当前用户在博客中的角色,如果其中任何一个是“博客所有者”,则返回true

首先,最好使用一些授权流程(如)来隔离这一点,但如果您坚持使用自己的方法,您可以使用
。detect

def is_blog_owner?(blog_id)
  if current_user && blog_id
    blog = Blog.find_by(id: blog_id)
    roles = current_user.roles_for_blog(blog)
    roles.detect do |role|
      role.role == 'Blog-Owner'
    end
  end
end

它返回枚举器中与块匹配的第一个元素,否则,如果没有匹配的元素,它将返回nil。

我不熟悉rails 4,但是当它通过if语句时,您的方法在结尾不会返回false(在“true”前面返回也会有帮助…)您应该在循环中使用
return
:如果role.role==“Blog Owner”
,则返回true。然后添加一个
false
作为最后一行。所以,如果用户是所有者,您的方法将返回true,或者返回false(默认情况下,ruby方法总是返回最后一行)。