什么是更像Ruby的方式来执行此命令?

时间:2011-01-09 21:56:07

标签: ruby-on-rails ruby

我想这样做:

sender_email = @request.user.paypal_email if @request.user.paypal_email == "paypal@anonymous.com"

所以基本上我想只在用户paypal电子邮件是"paypal@anonymous.com"时才执行命令。这很好,但似乎还有重构的空间。

3 个答案:

答案 0 :(得分:9)

@request.user.paypal_email

有些人会主张你只使用一个点'。 (See 'Law of Demeter'.)您可能需要考虑使用Rails 'delegate' method

class User < ActiveRecord::Base
  has_many :requests
end

class Request < ActiveRecord::Base
  belongs_to :user

  delegate :paypal_email, :to => :user
end

然后你可以写

@request.paypal_email

或者如果您愿意

class Request < ActiveRecord::Base
  belongs_to :user

  delegate :paypal_email, :to => :user, :prefix => true
end

@request.user_paypal_email

答案 1 :(得分:5)

由于此代码在您的控制器中,因此它肯定可以重构。您通常希望这样的逻辑在模型中,因为编写单元测试很容易,并且控制器的工作不是很了解用户模型。

有几种方法可以重构这个,但我建议将逻辑移到用户模型中,如下所示:

def User < ActiveRecord::Base
  def sender_email
    paypal_email if paypal_email == "paypal@anonymous.com"
  end
end

然后你的控制器不需要知道多少就可以做到:

sender_email = @request.user.sender_email

答案 2 :(得分:0)

当然,你可以使用块重写,但唯一的区别是未来的灵活性或“可读性”。也许你的问题应该是“轨道是否提供了这样做的东西?”。这个问题的答案并非我所知道的。如果您的代码符合您的要求,我认为没有理由对其进行更改。