【问题标题】:Should I worry about method reusing in a rails model?我应该担心在 Rails 模型中重用方法吗?
【发布时间】:2014-08-27 13:42:19
【问题描述】:

很久以前,我了解到您应该在模型上编写可重用的方法,这样您就不会在应用程序中出现重复的代码。当然,这是使用 PHP,它不像 ruby​​ 那样动态。

现在,我正在使用 Rails 设计一个 API,并且我仍在思考这个问题。所以,我的问题是:我应该创建一个方法User.login(user, password) 还是应该只使用User.find_by(user: user, password: password)

我以前也喜欢方法方法,因为它为我们提供了一些便利,例如上面的方法登录。 password 通常应该以某种方式加密,通过创建 login 方法我可以封装它。

你们觉得呢?

【问题讨论】:

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


    【解决方案1】:

    通常,您希望在对象上定义方法并从其他对象调用它们。这是面向对象编程的一个关键租户:消息传递。调用对象上的方法可以让该对象处理自己的内部结构。如果可能的话,您永远不想操作或查询另一个对象的内部结构。否则,当您更改该对象的内部结构时,您现在必须更改所有依赖这些内部结构的代码。

    为了说明使用您的示例,如果您有一天将 User 模型的密码属性(即列名)更改为 encrypted_password,则 User.login(user, password) 方法根本不需要更改,但 @987654326 @ 方法会。所以这是在创建脆弱的代码!

    成为DRY, Shy, and tell the other guy

    更新

    在 Rails 中,您会发现人们经常使用 Rails 的 Active Record 查询接口来替换对象上的常用函数,例如基于多个属性的 getter 和 setter。这通常被认为可以接受,因为例如批量分配可以大大简化您的代码。因为,在某种程度上,User.find_by(user: user, password: password) 实际上是传递给User 类的消息。我同意您对此的担忧,并认为通常至少应该定义一个命名范围来处理这个问题。和/或创建用于构建对象关系的类方法应该尽可能多地使用(例如,参见 this SO answer 我不久前就这个主题写的)。在构建 Rails 模型关系时只是有点松散。我认为这可能来自两件事:1) DHH(Rails 的创建者)在纯对象建模概念和抽象代码的简单性/可读性方面并不重要,2) 我认为一开始大多数 Rails 应用程序都是善良的玩具应用程序和人们习惯于不考虑过分设计它们。但是,无论哪种方式,根据您自己对权衡取舍的舒适程度,做您认为正确的事情。

    【讨论】:

    • 问题是,我看到很多很多程序员不遵循这种方法。他们 ORM 一切。所以,我同意你所说的(不错的链接,顺便说一句),但我最近意识到 ruby​​ 是一个全新的世界,我还不知道如何充分探索。这就是困扰我的原因,为什么程序员不在 Rails 代码中使用这种方法。
    • 这就是新手程序员和“专家”程序员之间的区别——理解和实施良好的编码实践。不过,它比应用实现更容易理解(这需要努力!)。因此,您会发现一些懒惰与一些“现在已经足够了”。我将更新我的答案,以包含更多关于为什么这个特定问题在 Rails 中经常发生的原因。
    • 我认为,如果您知道您将使用多个地方,请让自己的生活更轻松并封装此逻辑,以便您只更新一个代码区域而不是少数几个。我认为您会看到常见操作重复的示例,因为有时很难预见某些操作需要在多个地方发生,并且程序员不会花时间重构以前的代码以使用新接口。
    • 我认为@keith 的评论很好地总结了普遍的 Rails 观点。关键是 Rails 社区倾向于更喜欢快速简单的代码,而不是更难、更耗时但更好的设计(可能主要是通过调用不太紧密耦合的代码过早优化)。这并不一定是坏事,因为最终将你的产品推向市场才是最重要的——没有漂亮的代码。并且您将来总是可以从这种技术债务中重构痛点。另见:medium.com/@joaomilho/festina-lente-e29070811b84
    【解决方案2】:

    两者都没有。您几乎可以肯定想要使用像 devise 这样的 gem 来为您提供这些类型的方法。

    【讨论】:

    • Sure devise 添加了很多这样的功能,但我认为上面的示例只是为了给整个项目中更通用的方法提供一个示例。
    • 虽然编写小的可重用方法通常是一件好事。
    • @Keith,没错。我确实使用了 Devise,很棒的宝石!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 1970-01-01
    相关资源
    最近更新 更多