0

在 Spina 中有一个类Account

其中被称为方法:

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

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

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

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

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

PS 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
4

1 回答 1

1

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

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

此处查看gem 的代码(第 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,并询问他们是否正式支持自定义帐户属性的能力。

于 2020-07-12T02:13:17.313 回答