繁体   English   中英

Ruby on Rails'除非'不工作

[英]Ruby on Rails 'unless' not working

这是一个关于Ruby on Rails的帮助呼吁,以阻止我的血压达到危险水平......

Ruby版本:ruby 2.1.0p0(2013-12-25修订版44422)

Rails版本:Rails 4.0.3

基本上我正在创建一个Web应用程序,可以让您获得有关设计的反馈,但是当我在测试中显示标题时,我遇到'除非'语句的问题#index page

控制器(这适用于检索正确的测试):

def index

    # Gets all tests that have an end date before now
    @completed_tests = Test.where(["end_date < ?", DateTime.now]).order("end_date asc")

    # Gets all tests that have an end date after now        
    @current_tests = Test.where(["end_date > ?", DateTime.now]).order("end_date asc")

end

查看(测试#index)(这是导致我出问题的部分)

# This should be if there are no tests for the user, display the Blank state text
<% unless @completed_tests.nil? || @current_tests.nil? %>

        # If there are no completed tests this should not be displayed
        <% unless @completed_tests.nil? %>
            <h3>Completed Tests Section Header</h3>
        <% end %>


        <% @completed_tests.each do |test| %>
            # Do stuff (this works fine)
        <% end %>

        # If there are no current tests this should not be displayed    
        <% unless @current_tests.nil? %>
            <h3>Current Tests Section Header</h3>
        <% end %>

        <% @current_tests.each do |test| %>
            # Do stuff (this works fine)
        <%end%>

<% else %>

# This should be displayed if there are no completed or current tests
<p>Blank state text</p>

<% end %>

问题在于没有测试时显示标题,例如,当没有完成测试时显示已完成的测试标题但不应该显示,同样如果没有测试我将获得已完成的和当前测试标题而不是看到空白状态文本。

我试过的其他事情:

<% if @current_tests.nil? %>
    <h3>Completed Tests Section Header</h3>
<% end %>

上图:无论是否有测试,都会删除标题

<% if @current_tests %>
    <h3>Completed Tests Section Header</h3>
<% end %>

上图:无论是否有测试显示(与上面的原始代码相同)

任何帮助将不胜感激...

而不是使用obj.nil? ,你可以使用obj.blank? 在Rails中,也处理[] 在您的情况下,我认为您的查询可能会返回[]

<% unless @completed_tests.blank? %>
  <h3>Completed Tests Section Header</h3>
<% end %>

顺便说一句,我讨厌unless 我必须考虑一下它究竟意味着什么。 对我来说,理解起来要比if not很难。

对于后来的部分,

# This should be displayed if there are no completed or current tests
<p>Blank state text</p>

你需要(没有计算机测试)或(没有当前测试)

<% if @completed_tests.blank? || @current_tests.blank? %>
  <p>Blank state text</p>
<% end %>

或者(没有计算机测试)和(没有计算机测试)

<% if @completed_tests.blank? && @current_tests.blank? %>
  <p>Blank state text</p>
<% end %>

我不确定你的确需要什么,因为你的描述含糊不清。

我给Arie Shaw回答了一下,但是当我正在写一篇文章时,我觉得我只是发布了我的想法:

你使用.nil? 可能是问题(来自另一个SO帖子) -

。零? 可以在任何对象上使用,如果对象为零,则为true。

.empty? 可用于字符串,数组和散列,并在以下情况下返回true:

字符串长度== 0数组长度== 0哈希长度== 0运行.empty? 在nil的东西上会抛出一个NoMethodError。

如Arie所述, 如果未设置变量 (如果它不在内存中) .nil将返回true 我会说,因为你已经设置了@completed_tests变量(它会返回一个结果......也许是空白的),你的.nil? 方法将始终返回false,从而使您的逻辑不连贯:

在Ruby中,每个值都是一个对象。 所以,零也是一个对象。 实际上,它是NilClass的一个实例:

我会说你最好用Arie的blank? 回答,还是还有.empty?

<% unless @completed_tests.empty? || @current_tests.empty? %>

更新

这就是我要做的。 帮助程序未经测试,因此可能需要修复(特别是instance_variable_get方法):

#app/helpers/application_helper.rb
def tests(test)
  title = test.to_s.titleize
  content = "<h3>#{title} Tests Section Header</h3>"
  instance_variable_get(test).each do |test|
      content + "more html"
  end
  return content
end

<% case true %>
<% when @completed_tests.any? %>
  <%= tests(:completed) %>
<% when @completed_tests.any? %>
  <%= tests(:current) %>
<% else %>
  <p>Blank State Text</p>
<% end %>

我会在这里改变一些事情,以使逻辑更容易,并可能防止将来出现问题:

首先,确定测试的逻辑属于模型。 所以以下控制器代码:

# Gets all tests that have an end date before now
@completed_tests = Test.where(["end_date < ?", DateTime.now]).order("end_date asc")

# Gets all tests that have an end date after now        
@current_tests = Test.where(["end_date > ?", DateTime.now]).order("end_date asc")

应该

#test.rb

def completed
  self.end_date.to_i < Time.now.to_i 
end

def current
  self.end_date.to_i > Time.now.to_i
end

#test_controller.rb

def index
  @tests = Test.all
  @completed_tests = @tests.map(&:completed)
  @current_tests = @tests.map(&:current)
end

正如Arie Shaw所提到的那样, unless你很难缠头 - 特别是当你使用复杂的条件时。 所以我会改变这一行:

<% unless @completed_tests.nil? || @current_tests.nil? %>

部分中的组成部分。 就像是:

<% if @completed_tests.any? %> #any is the opposite equivalent of `blank` as in Arie Shaw's answer
  <%= render 'completed_tests' %>
<% end %>

<% if @current_tests.any? %> 
  <%= render 'current_tests' %>
<% end %>

<% if @current_tests.empty? && @completed_tests.empty? %>
   <p>Blank state text</p>
<% end %>

#_completed_tests.html.erb

<h3>Completed Tests Section Header</h3>

<% @completed_tests.each do |test| %>
  # Do stuff (this works fine)
<% end %>

#_current_tests.html.erb

<h3>Current Tests Section Header</h3>

<% @current_tests.each do |test| %>
  # Do stuff (this works fine)
<%end%>

通过这种方式,您可以一次提出一个问题,这样您就可以更容易地跟踪。

@completed_tests返回一个空数组,如果你做[].nil? ,现在在ruby中[].nil? 然后它会返回false ,使用blank? 相反,它是在rails, [].blank?定义的[].blank? 返回true 她是我在rails控制台上测试过的

2.0.0p247 :085 > a = Product.where("id =?", 10000)
  Product Load (0.5ms)  SELECT `products`.* FROM `products` WHERE (id =10000)
 => #<ActiveRecord::Relation []> 
2.0.0p247 :086 > a.nil?
 => false 
2.0.0p247 :087 > a.blank?
 => true 
2.0.0p247 :088 > [].nil?
 => false 
2.0.0p247 :089 >
2.0.0p247 :089 > [].blank?
 => true 

1代表Arie的回答

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM