我有一段代码在这一行:
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)
没有(返回的哈希仍然包含所有键)。这怎么可能?
因为属性返回一个带有键作为字符串而不是符号的哈希。
http://apidock.com/rails/ActiveRecord/Base/attributes
正如其他人所说,字符串!=符号。
puts :a == 'a'
# => false
发生这种情况是因为其中的键user.attributes
是字符串。您可以使用symbolize_keys
方法对它们进行符号化,然后使用except
这样的符号。
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)
# => {}
※ 附加信息
在上面写完之后,我找到了其他方法。
使用 Hash#deep_symbolize_keys 将所有键转换为符号!
{"a" => "hoge"}.deep_symbolize_keys!.except(:a) # => {}
使用 ActiveSupport::HashWithIndifferentAccess
{"a" => "hoge"}.with_indifferent_access.except(:a) # => {}
谢谢
Ruby 3 添加了 Hash#except 以返回不包括给定键及其值的散列:
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' }