【问题标题】:Ruby - how to multiply variables within a methodRuby - 如何在方法中乘以变量
【发布时间】:2016-08-10 20:15:27
【问题描述】:

我正在使用一种方法来尝试将两个变量相乘,如下所示 -

def total_amount
  self.quantity.to_i * self.event.price.to_i
end

我正在使用 Ruby on Rails 构建一个活动应用程序,该方法的目的是允许一个用户为付费活动预订多个空间。

该方法根本不起作用,因为当我点击付款时,金额仅显示为 0(零)。该方法在我的预订模型中,在我的预订控制器中,我有以下代码 -

class BookingsController < ApplicationController

  before_action :authenticate_user!

  def new
    @event = Event.find(params[:event_id])
    @booking = @event.bookings.new(quantity: params[:quantity])
    @booking.user = current_user
  end

  def create
    @event = Event.find(params[:event_id])
    @booking = @event.bookings.new(booking_params)
    @booking.user = current_user

    Booking.transaction do
      @event.reload
      if @event.bookings.count > @event.number_of_spaces
        flash[:warning] = "Sorry, this event is fully booked."
        raise ActiveRecord::Rollback, "event is fully booked"
      end
    end

    if @booking.save
      # CHARGE THE USER WHO'S BOOKED
      # #{} == puts a variable into a string
      Stripe::Charge.create(
        amount: @event.price_pennies,
        currency: "gbp",
        card: @booking.stripe_token,
        description: "Booking number #{@booking.id}")
      flash[:success] = "Your place on our event has been booked"
      redirect_to event_path(@event)
    else
      flash[:error] = "Payment unsuccessful"
      render "new"
    end

    if @event.is_free?

      @booking.save!
      flash[:success] = "Your place on our event has been booked"
      redirect_to event_path(@event)
    end
  end

  private

  def booking_params
      params.require(:booking).permit(:stripe_token, :quantity)
  end
end

我的 events.show 表单上有一个输入空间,允许用户输入他们需要的空间数量。预订表格有以下代码行,应该反映所需的总金额 -

<p>Total Amount<%= @booking.total_amount %></p>

我在两个变量中都添加了.to_i,因为没有这个我收到了 NilClass 错误。我该如何修改它以便该方法创建正确的输出?

【问题讨论】:

  • nil.to_i 为零,因此如果其中任何一个值为 nil,则乘法将返回零。
  • 在我使用的尝试中,两者都不会为零。我用 2 表示数量,用 1.50 英镑表示价格。但输出为零。
  • 这可能是因为货币符号。 '1.50'.to_i 是 1,'1.50'.to_f 是 1.50,'£1.50'.to_i 是 0。这就是 ruby​​ 字符串到整数转换的工作原理。您应该使用浮点数作为货币并在转换之前去掉£
  • 是不是就这么简单就用.to_f呢?
  • 不,因为£ 符号。如果你确定字符串的第一个字符是£,你可以直接使用string[1..-1].to_f。或查看the monetize gem,即Monetize.parse('£100.01').to_f

标签: ruby-on-rails ruby ruby-on-rails-4 model-view-controller methods


【解决方案1】:

您可以使用正则表达式去除您的货币符号

def total_amount
  quantity.to_i * strip_currency(event.price)
end

private

def strip_currency(amount = '')
  amount.to_s.gsub(/[^\d\.]/, '').to_f
end

【讨论】:

  • 您好,我尝试实现上述方法,但出现“未定义方法 gsub”错误。我该如何纠正这个问题?我觉得我非常接近得到我的问题的答案。希望你能做出回应。
  • 检查您获得的金额值是否为字符串或使用amount.to_s将其转换为字符串
  • 我应该在方法中使用金额,因为我没有将其存储在我的预订或活动表中吗?将amount.to_s放在上面的方法中,只会带来语法错误。
  • amount 是您传递给此方法的 event.price
  • 你在 event.price 中有什么价值
【解决方案2】:

如果您调用booking.new,则表示您正在创建类的实例,而self. 表示您正在使用类变量。

删除self

【讨论】:

  • 如果我错了,请原谅我,我很高兴这样做。但是,在实例方法的上下文中,我相信self 解析为实例,而不是类。如果在实例方法的上下文中,您想要访问类变量,您可以执行self.class.class_variable 之类的操作。因此,quantity * event.price应该self.quantity * self.event.price 相同。再次,如果我弄错了,请提前道歉。
  • 您可能是对的,但我认为这与上述响应有更多关系 - £ 符号将输出呈现为 0(零)。我认为这是主要问题。
  • @jvillian 完全正确;将self. 添加到方法的唯一情况是:1) 定义类方法,2) 在 self 上调用被同名局部变量遮蔽的方法,3) 消除对 self 的 setter 的歧义一个局部变量赋值,以及 4) 调用私有方法(当使用显式接收器调用时,即使该接收器是自己的,也会失败……除了私有 setter 的情况,为了避免语法歧义,会对其进行异常处理)。
猜你喜欢
  • 2013-08-04
  • 2012-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-23
  • 2011-02-19
  • 2012-01-07
  • 2011-08-27
相关资源
最近更新 更多