在不使用初始化方法的情况下将哈希传递给类

当我将一个散列传递给一个类时,我需要一个像这样的初始化方法:

class Dog

  attr_reader :sound

  def initialize(params = {})
    @sound = params[:sound]
  end

end

dog = Dog.new({sound:"woof"})
puts dog.sound

但是我碰到了一些代码(用于创建密码摘要),它在不使用初始化方法的Rails应用程序中工作,似乎工作得很好,它让我感到困惑,因为当我在其他地方尝试时它似乎没有工作。 以下是可用的示例代码(允许我传入哈希并初始化而不需要初始化方法):

class User < ActiveRecord::Base
  attr_reader :password
  validates :email, :password_digest, presence: true
  validates :password, length: { minimum: 6, allow_nil: true }
  def password=(pwd)
    @password = pwd
    self.password_digest = BCrypt::Password.create(pwd)
  end
end

注意:在创建操作中,我通过一个表单中的强参数传递一个散列,在一天结束时,它看起来像这样{“email”=>“joeblow@gmail.com”,“password”=>“ holymolycanoli”}

在这部分代码中没有初始化方法。 当我在pry或repl中尝试这样的事情(传入一个没有初始化方法的散列)时,它似乎不起作用(例如下面的代码不起作用):

class Dog

  attr_reader :sound

  def sound=(pwd)
    @sound = pwd
  end

end

dog = Dog.new({sound:"woof"})
puts dog.sound

我得到的错误是:

错误的参数数量(1代表0)

它是否允许我像这样或ActiveRecord传入哈希? 我很困惑,为什么它在这个上下文中的rails内工作,但在rails之外生成一个错误。 为什么这在轨道中工作?


如果你看看你有这个顶部:

class Dog < ActiveRecord::Base

这会导致你的类DogActiveRecord::Base继承,因此它获得了一系列允许你设置的方法。

现在当你打电话给例子:

Dog.create(password: 'some_password', username: 'some_username')

您在类对象上调用一个方法,然后返回该类的一个实例。

所以采取你的榜样

class Dog

  attr_reader :sound

  def sound=(pwd)
    @sound = pwd
  end

  def self.create data_hash
   new_dog = self.new #create new instance of dog class
   new_dog.sound = data_hash[:sound] #set instance of dog classes sound
   new_dog # return instance of dog class
  end

end

这基本上就是我们所说的工厂方法,它是一种接收数据并根据数据返回对象的方法。

现在我毫不怀疑ActiveRecord::Base正在做一些比这更复杂的事情,但这基本上是它在最基本的层次上所做的。

我也想指出,当从ActiveRecord::Base继承时,你也继承了它的'initialize'方法,所以你不必自己设置一个。 该类根据您在对数据库进行数据库迁移时设置的架构(通过铁路惯例)匹配该类时知道要创建的属性方法。


当你对ActiveRecord :: Base进行子类化时,会发生很多事情。 在看其他问题之前,我猜测Dog是一个rails ActiveRecord模型,你只是忘了添加

class Dog < ActiveRecord::Base
链接地址: http://www.djcxy.com/p/60959.html

上一篇: Passing in a hash to a class without using an initialization method

下一篇: Why does Hash#select and Hash#reject pass a key to a unary block?