在没有符号的情况下使用参数初始化新对象失败

Initializing new object with parameters fail without symbols

def initialize(user=nil, attributes={})
      @user = user
      (self.class.car_fields & attributes.keys.map{|i| i.to_sym }).each do |f|
        car[f] =  attributes[f] if attributes.key?(f)
      end
      validate!
    end 

方法调用

 attributes = { "has_car" => "true", "has_truck" => "true", "has_boat" => "true", "color" => "blue value", "size" => "large value" }
Car.new(user, attributes)

属性不会在我的模型中更新以进行验证。

但是,如果我传递一个包含所有符号的散列,它会起作用。

 attributes_symbols = { :has_car => "true", :has_truck => "true", :has_boat => "true", :color => "blue value", :size=> "large value" }

Car.new(user, attributes_symbols)

为什么当我传递符号时我的模型看到了字段,但在前一种情况下它表现得好像从未传递过字段?

因为在

attributes.keys.map{|i| i.to_sym }

您将每个键映射到一个符号,然后在 attributes 中将它们作为符号访问,当它们是字符串键时。

所以你最终会做这样的事情:

{ "has_car" => "true", "has_truck" => "true", "has_boat" => "true", ... }[:has_car]
# nil

一个可能的解决方案是创建一个新变量,在 attributes 上调用 with_indifferent_access:

indifferent_access_attributes = attributes.with_indifferent_access
(self.class.car_fields & indifferent_access_attributes.keys.map(&:to_sym)).each do |field|
  seller[field] = indifferent_access_attributes[field]
end

另一种方法是只定义一种格式的键并在整个过程中使用它。所以,不要映射到 attributes 键的符号。