简体   繁体   English

如果在Ruby / Rails代码块之间的其他地方重构这个

[英]Refactor this if else between block of Ruby/Rails code

Here's the code. 这是代码。 Basically, the user selects a billing day (the 1st of each month, or the 15th of each month). 基本上,用户选择结算日(每月的第1天,或每月的第15天)。 The start_date is when the "contract" begins, the expire_date is when it expires. start_date是“合同”开始的时候, expire_date是它到期的时候。

So, if today is the 3rd, and they want to be billed on the 15th, then simply go to the 15th day of the current month. 所以,如果今天是第3天,并且他们希望在15日收费,那么只需转到当月的第15天。 However, if today is the 3rd and they want to be billed on the first, then get the 1st day of next month... etc. 但是,如果今天是第3名,并且他们希望在第一次收费,则获得下个月的第1天......等等。

if params[:billing_day] == 1 && start_date.day > 1
  expire_date = start_date.at_beginning_of_month.next_month
elsif params[:billing_day] == 15 && start_date.day < 15
  expire_date = start_date.change(:day => 15)
elsif params[:billing_day] == 15 && start_date.day > 15
  expire_date = start_date.at_beginning_of_month.next_month.change(:day => 15)
else
  expire_date = start_date.change(:day => params[:billing_day])
end

It just seems crazy, surely it can be simplified in Rails. 它看起来很疯狂,肯定可以在Rails中简化。 Thanks! 谢谢!

I would write something along the lines of 我会写一些东西

expire_date = start_date.change(:day => params[:billing_day])
if expire_date <= start_date
  expire_date += 1.month
end

You'd need to validate that a valid billing day was picked before this 您需要验证在此之前选择了有效的结算日

Came up with this. 想出了这个。 But not sure if it's good idea 但不确定这是不是好主意

expire_date = if params[:billing_day] == 1 && start_date.day > 1
  start_date.at_beginning_of_month.next_month
elsif params[:billing_day] == 15 && start_date.day < 15
  start_date.change(:day => 15)
elsif params[:billing_day] == 15 && start_date.day > 15
  start_date.at_beginning_of_month.next_month.change(:day => 15)
else
  start_date.change(:day => params[:billing_day])
end

And what if params[:billing_day] == 15 && start_date.day == 15 ? 如果params[:billing_day] == 15 && start_date.day == 15怎么办? What should happen? 应该怎么办?

Came up with this also, but it behaves a little different in the case of start_date.day == 15 也想到了这一点,但在start_date.day == 15的情况下它的行为有点不同

expire_date = if params[:billing_day] == 1 && start_date.day > 1
  start_date.at_beginning_of_month.next_month
elsif params[:billing_day] == 15
    if start_date.day < 15
        start_date.change(:day => 15)
    else
        start_date.at_beginning_of_month.next_month.change(:day => 15)
    end
else
   start_date.change(:day => params[:billing_day])
end

Also notice that in Rails it's good practice to put logic in models, and since you are using params[] you are doing it in the controller. 另请注意,在Rails中,将逻辑放入模型中是一种很好的做法,因为您使用的是params [],所以您在控制器中执行此操作。

class ExpireDate

  def initialize(billing_day, start_date)
    @billing_day = billing_day
    @start_date = start_date
  end 

  def expires_on
    if billing_day == 1
      return billing_on_1st
    elsif billing_day == 15
      return billing_on_15th
    else
      raise "Unknown billing_day"
    end
  end

  def billing_on_1st
    if @start_date.day > 1
      return @start_date.at_beginning_of_month.next_month
    else
      return @start_date.change(:day => @billing_day)
    end
  end

  def billing_on_15th
    if @start_date.day < 15
      return @start_date.change(:day => 15)
    else
      return @start_date.at_beginning_of_month.next_month.change(:day => 15)
    end
  end
end


expire_date = ExpireDate.new(params[:billing_day], start_date).expires_on

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

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