- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我使用 readonly?
函数将我的 Invoice
发送后标记为不可变;对于 by InvoiceLine
,我只是将 readonly?
函数代理到 Invoice
。
一个简化的例子:
class Invoice < ActiveRecord::Base
has_many :invoice_lines
def readonly?; self.invoice_sent? end
end
def InvoiceLine < ActiveRecord::Base
def readonly?; self.invoice.readonly? end
end
这很好用,除了在一个特定的场景中我想更新 InvoiceLine
而不管 readonly?
属性。
有什么办法吗?
我尝试使用 save(validate: false)
,但这没有效果。我查看了 AR 源代码中的 persistence.rb
,这似乎就是这样:
def create_or_update
raise ReadOnlyRecord if readonly?
...
end
有没有明显的方法可以避免这种情况?
我可能会在 Python 中做的(有点肮脏的)解决方法:
original = line.readonly?
line.readonly? = lambda: false
line.save()
line.readonly? = original
但这在 Ruby 中行不通,因为函数不是一流的对象......
最佳答案
您可以非常轻松地在实例化对象中重新定义方法,但语法是定义而不是赋值。例如。在更改需要调整其他只读对象的架构时,我使用这种形式:
line = InvoiceLine.last
def line.readonly?; false; end
等等,状态被覆盖了!实际发生的是对象的特征类而不是其类中的 readonly?
方法的定义。不过,这实际上是在对象的内部进行挖掘;在架构更改之外,这是一种严重的代码味道。
一个粗略的替代方案是强制 Rails 将更新的列直接写入数据库:
line.update_columns(description: "Compliments cost nothing", amount: 0)
它是大规模杀伤性的:
InvoiceLine.where(description: "Free Stuff Tuesday").update_all(amount: 0)
但同样,它们都不应该出现在迁移之外的生产代码中,并且偶尔出现在一些精心编写的框架代码中。这两个绕过了所有验证和其他逻辑,并冒着使对象处于不一致/无效状态的风险。最好以某种方式在模型代码和交互中明确传达需求和行为。你可以这样写:
class InvoiceLine < ActiveRecord::Base
attr_accessor :force_writeable
def readonly?
invoice.readonly? unless force_writeable
end
end
因为那时客户端代码可以说
line.force_writable = true
line.update(description: "new narrative line")
我仍然不太喜欢它,因为它仍然允许外部代码指示内部行为,并且它使对象的状态发生变化,而其他代码可能会遇到这种情况。这是一个更安全、更 ruby 色的变体:
class InvoiceLine < ActiveRecord::Base
def force_update(&block)
saved_force_update = @_force_update
@_force_update = true
result = yield
@_force_update = saved_force_update
result
end
def readonly?
invoice.readonly? unless @_force_update
end
end
然后客户端代码可以写:
line.force_update do
line.update(description: "new description")
end
最后,这可能是最精确的机制,您可以只允许更改某些属性。您可以在 before_save 回调中执行此操作并抛出异常,但我非常喜欢使用依赖于 ActiveRecord 脏属性模块的验证:
class InvoiceLine < ActiveRecord::Base
validate :readonly_policy
def readonly_policy
if invoice.readonly?
(changed - ["description", "amount"]).each do |attr|
errors.add(attr, "is a read-only attribute")
end
end
end
end
我很喜欢这个;它将所有领域知识放入模型中,它使用支持的和内置的机制,不需要任何猴子修补或元编程,不避免其他验证,并为您提供可以一直传播回来的漂亮错误消息到 View 。
关于ruby-on-rails - 绕过只读?保存 ActiveRecord 时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27723375/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!