Rails无法识别是非 [英] Rails not recognizing true or false

查看:50
本文介绍了Rails无法识别是非的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我本来应该很简单的东西,但是却把我杀死了.

I have something that should be really simple, but it's killing me.

l = LineItem.first
#<LineItem id: 5, product_id: 1, quantity: 1, price: #<BigDecimal:7f7fdb51a3f8,'0.999E3',9(18)>, cart_id: 5, discount_percentage: 10, discount_amount: nil, discount_active: true, created_at: "2012-01-12 16:17:41", updated_at: "2012-01-12 16:17:41">

我有

l.discount_percentage.blank?
=> false

所以,我有以下方法:

  def total_price
    discount_amount = 0 if discount_amount.blank?
    discount_percentage = 0 if discount_percentage.blank?

    discounted_amount_from_percent = price*(discount_percentage.to_f/100)

    applicable_discount = [discount_amount,discounted_amount_from_percent].max

    return (price-applicable_discount)
  end

但是当我这样做时:

l.total_price

而不是返回899,而是返回999(这意味着if discount_percentage.blank?根本不起作用!)

Instead of returning 899, it returns 999 (meaning that the if discount_percentage.blank? didn't work at all!)

或者如果语法为true/false,则语法WHATEVER_HERE仅在Rails视图中起作用?

Or the syntax WHATEVER_HERE if true/false only work in the View on Rails??

推荐答案

这里出现了问题:

discount_amount = 0 if discount_amount.blank?
discount_percentage = 0 if discount_percentage.blank?

Ruby从上到下,从左到右看到"变量,因此在那一行中他首先看到了一个局部变量(discount_amount =),因此他认为discount_mount.blank?中的discount_amount这件事是相同的局部变量(而不是实例方法.您认为该变量尚未定义,但是Ruby已经发现了它). discount_amount尚无任何值,它设置为默认值nil,因此nil.blank?成功,并分配了discount_percentage = 0. discount_percentage的同上.这是一个演示代码段:

Ruby "sees" variables from top to bottom and from left to right, so in that line he first sees a local variable (discount_amount =) so he decides this discount_amount thing in discount_mount.blank? is that same local variable (and not the instance method. You think the variable is not defined yet, but Ruby has already spotted it). Not having any value yet, discount_amountit set to default value nil, so nil.blank? succeeds and the assignment discount_percentage = 0 is made. Ditto for discount_percentage. Here's a demo snippet:

class ExampleClass 
  def run
    x = "it works as expected" if x == "x"
    x
  end

  def run2
    if x == "x"
      x = "it works as expected" 
    end
    x
  end

  def run3
    xy = "it works as expected" if x == "x"
    xy
  end

  def x; "x"; end
end

p ExampleClass.new.run #=> nil
p ExampleClass.new.run2 #=> "it works as expected"
p ExampleClass.new.run3 #=> "it works as expected"

第1步:不要对本地变量和实例方法使用相同的名称.无论如何,这通常是一个坏主意,因为您无法跟踪正在使用的那个,但是在这种情况下,它确实咬住了您.

Step 1: don't use the same names for local variables and instance methods. That's usually a bad idea anyway because you lose track of which one you are using, but in this case it has really bitten you.

第2步:进行数学计算时,请勿编写命令式代码!的确,数学(在典型应用程序中所做的事情的9%,(10-X)%的不可避免的副作用)在表达式,而不是语句.我会写:

Step 2: Do not write imperative code when you're doing math calculations! Really, maths (9X % of the things you do in a typical application, (10-X)% being unavoidable side-effects) play well with expressions, not with statements. I'd write:

def total_price
  final_discount_amount = discount_amount || 0
  final_discount_percentage = discount_percentage || 0
  discounted_amount_from_percent = price * (final_discount_percentage.to_f/100)
  applicable_discount = [final_discount_amount, discounted_amount_from_percent].max
  price - applicable_discount
end

这篇关于Rails无法识别是非的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆