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部分,给出了带有符号的示例