Hash.except()不适用于符号键

时间:2012-08-16 08:13:44

标签: 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)

没有(返回的散列仍然包含所有键)。这怎么可能?

4 个答案:

答案 0 :(得分:8)

因为属性返回带有键的哈希,而不是符号。

http://apidock.com/rails/ActiveRecord/Base/attributes

正如其他人所说,String!= Symbol。

puts :a == 'a'
# => false

答案 1 :(得分:7)

这是因为user.attributes中的键是字符串。您可以使用symbolize_keys方法对其进行符号化,然后将except与此类符号一起使用。

user.attributes.symbolize_keys.except(:created_at, :created_by, :updated_at, :updated_by, :id)

答案 2 :(得分:0)

我不希望在某些情况下这种行为(例如处理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) # => {}

感谢

答案 3 :(得分:0)

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' }