Rails 一个 rails model 的方法求美化

wuwx · 2013年06月29日 · 最后由 wuwx 回复于 2013年06月30日 · 3204 次阅读
class Account < ActiveRecord::Base
  has_many :invoices
  def invoice
    invoices.where(:payment => :consume, :state => :enabled).where("started_at < '#{Time.now}'").where("expires_at > '#{Time.now}'").first
  end
end

用于返回当前账户下有效账单的函数:)这个写法看上去好不爽~~~~~

把子条件在 Invoice 里面写成若干条 scope?

这个写法感觉有点问题... 如果账户下只会有一条有效账单的话,最后的 .first 就多余;如果账户可以有不止一条有效账单,那 .first 就只能返回一条。

噢,我搞错了,是用来把 Relation 转成 Invoice 的 ...

#2 楼 @blacktulip 一个账户当前只有 1 条或 0 条有效账单呀,相当于本月的月租那种性质

#3 楼 @wuwx 额我搞错了... sorry

#4 楼 @blacktulip 也怪我没写清楚哈

has_many 接受一个 block,可以给关联集合定义方法 http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/has_many#461-User-a-block-to-extend-your-associations

我觉得顶楼写法也没问题

我也觉得这样写很正常..

拆成一些 scope:

class Account < ActiveRecord::Base

  has_many :invoices

  def invoice
    invoices.consume.active.first
  end
end

class Invoice < ActiveRecord::Base

  belongs_to :account

  scope :consume, -> { where( payment: :consume ) }
  scope :enabled, -> { where( state: :enabled ) }
  scope :active,  -> { enabled.where( 'stated_at < ? AND expires_at > ?', Time.now ) }
end

@Rei 正解,加到 has_many 的 condition 选项更好

顶楼的写法打破了 "tell don't ask" 的基本规则。Account 模型不应该知道那么多关于 Invoice 的细节。Implementation details 应该全部放到 Invoice 模型里。

类似 #8 楼 @qhwa 的这样。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号