【问题标题】:Overwrite method in Ruby moduleRuby 模块中的覆盖方法
【发布时间】:2020-07-12 00:47:05
【问题描述】:

在 Spina 中有一个类Account

其中被调用的方法:

serialized_attr_accessor :google_analytics, :google_site_verification, :facebook, :twitter, :instagram, :youtube, :linkedin, :google_plus, :theme

我在我的 /app/models/spina 目录中创建了一个带有 Account 类的模块 Spina,其代码与gem 的帐户模型,唯一改变的行是:

serialized_attr_accessor :google_analytics, :google_site_verification, :facebook, :twitter, :instagram, :youtube, :linkedin, :twitch, :github, :theme

(基本上多加了2个属性)

我非常确定,这不是正确的方法,而且它缺乏关于如何在 Rails 中工作的知识。很高兴提供信息,这里有什么正确的解决方案/方法。

附: Ruby 和 Rails 的新手,所以请在回答时非常严格。

更新 12.07.20-1 我创建了一个猴子补丁:

~/app/models/spina/account.rb

module Spina
  class Account < ApplicationRecord
    # here putted all code from [Account](https://github.com/SpinaCMS/Spina/blob/master/app/models/spina/account.rb)
  end
end

【问题讨论】:

  • 您创建了“带班级帐户的模块脊柱”?这是什么意思?你能给出定义吗?
  • 添加了更新更新 12.07.20-1,导致 cmets 中的格式很糟糕。

标签: ruby-on-rails ruby spina-cms


【解决方案1】:

免责声明:我自己没有使用过 Spina,也不了解该项目。

这与其说是 Rails 问题,不如说是关于 gem 以及它的作者如何设想它被定制的。

通过查看 gem here 的代码(第 16-29 行),serialized_attr_accessor 似乎是 Spina::Account 的一个类方法,它遍历提供的每个参数并动态添加 getter 和 setter 方法。

一般来说,你是对的,在 Rails 中你可以添加一个文件app/models/spina/account.rb 并重新打开类。但是,它不会取消其他文件中类的定义。因此,仍会调用原始的 serialized_attr_accessor 调用 - 在这种特殊情况下您不能忽略它。

只要您希望添加属性而不是删除任何属性,您就可以执行以下代码并且它应该具有所需的行为。您可以将此代码放入初始化程序中(例如,在 config/initializers/spina.rb 下 - config/initializers 下的所有文件作为 Rails 启动过程的一部分按字母顺序运行):

Spina::Account.serialized_attr_accessor :twitch, :github

但是,虽然此修复程序今天可能对您有用,但如果 Spina 的作者未指定此可扩展性作为 gem 接口的一部分受支持,那么您将面临明天的风险(更准确地说 - 在 Spina 的下一个版本中) 它可能会破裂。很可能作者从未打算公开 serialized_attr_accessor,并且可能会在下一个版本中重命名/删除/更改其行为 - 破坏您的应用程序。

一般来说,打开类(称为“猴子补丁”)和调用非公共方法(或非预期接口)是一种应谨慎使用的做法,即使它可以在 Ruby 中完成,因为您正在耦合您的代码使用 gem 的实现。

对于这个“修复”还有一点需要注意。您添加的这两个属性在数据库中不是持久的。它们只存储在内存中。我不确定其他领域是否仍然存在,因为我不熟悉宝石。但是如果你需要它们持久化,你将不得不在 Rails 中添加一个迁移。您可以创建一个迁移来修改spina_accounts 表,但这听起来是个坏主意,因为它将您的应用程序与其实现紧密结合在一起。您还可以考虑创建自己的 accounts 表,通过引用帐户记录(例如 spina_account_id)来扩展 Spina 帐户并添加您需要的额外字段。

无论哪种方式,我建议在gem的github页面上打开一个issue,询问他们是否正式支持自定义帐户属性的能力。

【讨论】:

  • 这不是一个可行的解决方案,但这个答案给了我一个方向,我应该采取行动来解决问题,并且还提供了有关 Rails 内容的更多信息。因此,标记为“已接受”,因为如前所述,与其说是关于 Rails,不如说是关于 gem。非常感谢@AmitA 的回复。
猜你喜欢
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 2013-07-10
  • 1970-01-01
  • 2016-12-06
  • 2014-06-04
  • 2021-01-06
相关资源
最近更新 更多