Ruby on rails Hash.except()不';不能使用符号键
我有一段代码,其中这一行:Ruby on rails Hash.except()不';不能使用符号键,ruby-on-rails,ruby,ruby-on-rails-3.2,Ruby On Rails,Ruby,Ruby On Rails 3.2,我有一段代码,其中这一行: user.attributes.except('created_at', 'created_by', 'updated_at', 'updated_by', 'id') 起作用(返回散列,其中作为参数传递的键从散列中移除),而将其更改为: user.attributes.except(:created_at, :created_by, :updated_at, :updated_by, :id) 没有(返回的哈希仍然包含所有键)。这怎么可能呢?因为属性返回一个散列
user.attributes.except('created_at', 'created_by', 'updated_at', 'updated_by', 'id')
起作用(返回散列,其中作为参数传递的键从散列中移除),而将其更改为:
user.attributes.except(:created_at, :created_by, :updated_at, :updated_by, :id)
没有(返回的哈希仍然包含所有键)。这怎么可能呢?因为属性返回一个散列,其中键是字符串,而不是符号 正如其他人所说,字符串!=象征
puts :a == 'a'
# => false
这是因为
user.attributes
中的键是字符串。您可以使用symbol_keys
方法对它们进行符号化,然后使用除
外的类似符号
user.attributes.symbolize_keys.except(:created_at, :created_by, :updated_at, :updated_by, :id)
我不希望在某些情况下出现这种行为(例如处理http json响应) 所以我添加了一些改进
module HashUtil
refine Hash do
def eager_except(*args)
proc = Proc.new do |key|
case
when key.is_a?(Symbol)
key.to_s
when key.is_a?(String)
key.to_sym
else
nil
end
end
eager_args = (args + args.map(&proc)).compact
except(*eager_args)
end
end
end
using HashUtil
hash = { a: 'a', "b" => 'b' }
hash.eager_except('a', :b)
# => {}
※其他信息
在写了上面的内容之后,我找到了其他的方法
使用哈希#深_symbol_键将所有键转换为符号
{"a" => "hoge"}.deep_symbolize_keys!.except(:a) # => {}
使用ActiveSupport::HashWithInferenceTaccess
{"a" => "hoge"}.with_indifferent_access.except(:a) # => {}
感谢Ruby 3添加了散列#除了返回一个不包括给定键及其值的散列之外:
irb(main):001:0> user_details = { name: 'Akhil', age: 25, address: 'India', password: 'T:%g6R' }
irb(main):002:0> puts user_details.except(:password)
=> { name: 'Akhil', age: 25, address: 'India' }
这可能是因为符号不必与字符串相同,并非总是如此equal@Marcin好了,符号永远不等于字符串。我真不敢相信这有多愚蠢。出于某种原因,我相信Ruby散列具有某种黑魔法,允许您使用同一个键的字符串或散列“表示”。我刚刚发现,我所有的哈希运算都有效的唯一原因是因为我总是使用符号!您还可以将任何
散列
转换为散列无差异访问
,然后您可以使用字符串和符号进行访问。Rails使用了很多(非常用户/开发人员友好),这可能是混淆的一部分:)另一部分混淆是Rails api文档,在Hash#except部分,给出了带有符号的示例