重构Fat ActiveRecord模型,现在怎么办?

时间:2013-04-05 08:01:10

标签: ruby-on-rails activerecord refactoring

我一直在使用CodeClimate来改进我的代码库,我有一个模型类,它正在落在“方法之外的定义”和“总体复杂性”上,对于那些不使用CodeClimate的方法,除了方法之外的定义指的是类定义,如关联和验证。整体的总体复杂性就是它所说的,即我的个体方法中没有一个太复杂,总体来说这个类很复杂。

现在我很欣赏这可能是一个错误的立场,但我的分数上的D课很烦人,我可以做更多的事情来改善这个课程,所以我的问题是:

如果我需要做什么来简化这个ActiveRecord类呢?

我的主要问题是我已经用尽所有关于重构胖模型的方法,使用这篇文章http://blog.codeclimate.com/blog/2012/10/17/7-ways-to-decompose-fat-activerecord-models/和类似的,我基本上留下了:

  • 范围x2
  • attr_accessible x2
  • carrierwave mount x1
  • 验证者x4
  • association x16
  • accepted_nested_attributes_for x1
  • 钩子,例如after_save x3
  • 使用各种其他属性进行计算的方法,使我的观点更具语义性,更易于理解
  • 围绕关联的方法,处理空关联,合并关联

它是一个封闭的源项目,但鉴于此类中缺少域逻辑,我在这里分享了它。 https://gist.github.com/msaspence/5317419

1 个答案:

答案 0 :(得分:3)

回调是地狱。我的意思是,它们很有用,但它们会使你的模型过载。

你的控制器中是否有动作来处理未发布的内容?

如果是这样(我希望如此),可以将其移动/提取到服务对象:

after_save :email_author_if_first_published
def email_author_if_first_published
  if pending_was == true && pending == false
  self.create_activity key: 'action.publish'
  delay.send_action_published_email
end
end

def send_action_published_email
  ActionAuthorMailer.action_published(self, self.user).deliver
end

这不应该属于模型,一些演示者应该更好:

def mixpanel_data_points
  {
    campaign_id: campaign_id,
    cause_id: cause_id
  }
end

def open_graph_type
  'campaign_action'
end

def facebook_invite_message
  "Please help me raise awareness on PatientsCreate. It'll take you 5 seconds and could create genuine change. Thanks"
end

def percentage_completed
  v = (participation_count.to_f/participation_target_count.to_f)*100
  v > 100.0 ? 100.0 : v
end

这似乎不太好:

after_update :update_campaing_actions_count
def update_campaing_actions_count
  Campaign.decrement_counter(:actions_count, self.campaign_id_was)
  Campaign.increment_counter(:actions_count, self.campaign_id)
end

因为即使未更改campaign_id,您也会这样做


这看起来很糟糕:

def url
  open_graph_url "/actions/#{id}"
end

不能说得多,我不知道其他方法中的纯粹数据或表现是什么