【问题标题】:Ruby on Rails ActiveRecord ConventionsRuby on Rails ActiveRecord 约定
【发布时间】:2015-05-12 16:39:36
【问题描述】:

我们正在尝试为一个项目建立最佳实践,并且我们正在讨论应该将 SQL 和 ActiveRecord 方法放在哪里。

我的理解是,您希望尽可能多地保留控制器之外的逻辑。我认为我们同意属于模型的复杂 SQL 查询,但我们不同意简单的 AR 方法应该存在于何处,无论是在控制器中还是在模型中。

所以用一些简单的东西,比如:

client = Client.find(10)

理想情况下它会存在于模型或控制器中吗?我知道这可能没有太大/任何区别,答案也无所谓,但对这个问题的任何见解都会很棒。

【问题讨论】:

  • client = Client.find(10) 是一个相当简单的操作,并且有点脱离上下文,所以我会说它可能会进入控制器或模型,具体取决于它执行的原因。在没有其他指导的情况下,我可能会说控制器。约定是控制器和视图对代码轻描淡写,代码在模型中(并在助手中查看帮助代码),但这是一个 约定 (不是绝对规则)原因是很多代码都与排序、筛选和处理数据有关,这与模型相关。控制器可以有一些代码。 :)
  • 这是一个从博客中读到的讨论:“复杂的查询(即,比简单的查找更复杂);一般来说,你不应该使用 where 方法,或者任何其他类似的查询构建方法,在模型类本身之外”。我现在才意识到他说 find 可以在控制器中使用,那么我认为 Client.where("first_name='Carly'") 应该在控制器之外使用呢?
  • 对于Client.where("first_name='Carly'"),我仍然会说这取决于(根据上下文)。 :)
  • 您能否就何时将其留在控制器中以及何时将其抽象为模型做出一般性断言?
  • 我在想,如果它是在提供常用数据过滤器的上下文中,那将是模型。如果它被用作基于用户操作的选择器来指导视图中发生的事情,那么控制器。管制员就是交通警察(我从来不喜欢这个比喻,但我猜它在这里行得通)。

标签: ruby-on-rails ruby ruby-on-rails-3 activerecord


【解决方案1】:

对此没有一个好的答案,我觉得这很可能会因此而关闭,但无论如何都可以。

Client.find(10)Client.where("first_name='Carly'") 是您可以进行的最简单的查询。您根本无法用模型方法替换第一个。第二个我想你可以创建一个search 方法,但这可能还为时过早。

我认为这些文章的重点是你不希望在你的控制器中出现这样的东西:

Client.where("created_at > X").where("some_flag = true").order('created_at DESC')

这是命名范围(或其中几个)的一个非常明确的候选者。

也就是说,有时我会将它留在我的控制器中,因为它非常特定于该控制器,并且不会在其他任何地方(永远)使用,因此恕我直言,将其干燥并没有多大意义。

但是,大多数情况下,当您开始这样做时,您会意识到可以将一些常用功能提取到模型中,以便在其他地方使用。

【讨论】:

  • 我认为这是我们正在寻找的核心。感谢您花时间回答!
【解决方案2】:

除了scopes 类之外,您还可以考虑使用 finders 模型,从模型和控制器中提取查询。

看看Gitlab handles it如何。

【讨论】:

  • 谢谢安德烈,我以前没听说过finders 模型。这是一个有趣的概念,感谢您的反馈。
【解决方案3】:

我真的认为这里的“核心”原则是 DRY 和 KISS。

如果您有多个控制器需要的相对较长的查询(几个 where 子句、joins 等),请将其提取为范围。

如果您有一个相当长的查询,似乎压倒了整个控制器方法,您可能应该将其提取为一个范围。

【讨论】:

  • 感谢艺术。我认为我们应该如何处理简单与不简单的 ActiveRecord 方法并抽象出范围变得更加清晰。
  • 不客气@CarlyL。很高兴我能帮上忙。祝你好运!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
相关资源
最近更新 更多