为什么不使用符号而不是字符串来访问Rails模型属性?

Geo*_*pty 6 ruby attributes symbols model ruby-on-rails

我需要在数据库更新之前和之后比较一些Rails(2.3.11)模型属性值,所以我首先找到我的记录并将现有属性值保存在哈希中,如下所示:

id = params[:id]
work_effort = WorkEffort.find(id)

ancestor_rollup_fields = {
    :scheduled_completion_date => work_effort.scheduled_completion_date
}

work_effort.update_attributes(params.except(:controller, :action))
#etcetera
Run Code Online (Sandbox Code Playgroud)

注意我坚持使用符号作为哈希键的"最佳实践".

然后我有一个方法,如果哈希值和模型属性中的值不匹配,则采用模型和哈希来确定可能采取的其他步骤.为了确定这一点,我尝试在每个循环中获取模型属性值,但我最初得到的是:

def rollup_ancestor_updates(work_effort, ancestor_rollup_fields)
    ancestor_rollup_fields.each do |key, value|
        model_val = work_effort.attributes[key] #nil
        #etcetera
Run Code Online (Sandbox Code Playgroud)

在上面的调试中,我注意到将字符串硬编码为键:

work_effort.attribute['scheduled_completion_date']
Run Code Online (Sandbox Code Playgroud)

返回所需的值.那么在我的每个块中我尝试了以下它并且它有效:

model_val = work_effort.attributes[key.to_s]
Run Code Online (Sandbox Code Playgroud)

有没有不同的方法来做到这一点?对我来说,仅仅3个月的Ruby/Rails经验,使用符号作为散列键就像规定的最佳实践一样令人困惑,但是必须在符号上调用.to_s才能获得模型属性.有没有其他人经历过这个,解决过这个,也被这个混淆了?提前致谢

Wiz*_*Ogz 11

当您#attributes在AR实例上调用时,返回的Hash 具有字符串键,这就是为什么作为哈希索引的符号在您的情况下不起作用的原因.有一个Hash被调用的子类,HashWithIndifferentAccess它自动将符号索引转换为字符串.

经常在Rails中你会遇到HashWithIndifferentAccess实例.一个完美的例子是您在控制器和视图代码中访问的params变量.

尝试使用 work_effort.attributes.with_indifferent_access[key]

真的,它只是做同样的事情,但它在幕后做.


Yur*_*ang 6

您可以使用自己的方法覆盖属性方法.

打开WorkEffort类

class WorkEffort
  def attributes
    super.symbolize_keys
  end
end
Run Code Online (Sandbox Code Playgroud)

然后,当您调用work_effort.attributes时,您将在哈希中使用符号化键.