简化此条件语句

时间:2011-02-08 04:14:50

标签: ruby-on-rails

我在Rails中编写了一个相当复杂(对我来说)的语句。在我show.html.erb的{​​{1}}下,这是用户的个人资料。每个Person.rb在数据库中都有post列,其值为statusdraft

published

这是问题所在。假设<% if @posts.blank? %> No post. <% else %> <% if @person == current_user %> <% @posts.each do |post| %> Post title... (where all published and draft posts are shown) <% end %> <% else %> <% @posts.each do |post| %> <% if post.status == "published" %> Post title (where only published posts are shown, draft posts are hide from other users) <% end %> <% end %> <% end %> <% end %> 有1个发布的帖子和1个草稿帖子,它运行正常;但如果User A有2个草稿帖子,那么右边没有帖子会显示给其他用户,但我希望它显示User B,就像前2行代码一样。

我在No post引导here中尝试了named_scope,但是当我申请时。发布它只是给我一个未定义的错误。

请教我如何做到这一点。非常感谢你。

3 个答案:

答案 0 :(得分:2)

我会做以下事情:

为帖子创建状态范围。

class Post
  named_scope :by_status, lambda { |status| {:conditions => {:status => status} } }
end

将一些逻辑移入控制器:

class PostsController
  def index
    @person = Person.find(params[:person_id])
    if current_user == @person
      @posts = @person.posts
    else
      @posts = @person.posts.by_status('published')
    end
  end
end

写下您的观点:

<% if @posts.empty? %>
  No posts code
<% else %>
  <% @posts.each do |post| %>
    Post title...
  <% end %>
<% end %>

此解决方案应该干掉您的代码并将更多逻辑移入您的模型中。

答案 1 :(得分:0)

要以最快捷的方式解决您的问题,我只会在第一行中排除草稿帖子,如下所示:

if (@person == current_user) ? @posts.blank? : @posts.select({ |x| x.status == 'published' }).blank?

但这并没有真正简化你的整体行动。这在视图中是一个非常常见的问题(有条件地基于两个不同的条件做一件事),并且希望更智能的人可以共享更好的解决方案。与此同时,我为您提供此服务。

答案 2 :(得分:0)

<% @posts.to_a.each do |post|
     if @person == current_user || post.status == 'published' %>
       ...
  <% end 
   end %>

.to_a会使[]中的nil成为{{1}},所以它可能只会减少到此...