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

时间:2015-05-16 23:25:10

标签: ruby-on-rails ruby

当我将哈希传递给类时,我需要一个像这样的初始化方法,这显然是不正确的印象:

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

注意:在创建操作中,我通过表格中的强参数传递哈希值,在一天结束时,看起来像这样{&#34; email&#34; =&gt;&#34; joeblow @ gmail.com&#34;,&#34;密码&#34; =&gt;&#34; 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之外产生错误。为什么这在rails中起作用?

2 个答案:

答案 0 :(得分:0)

当您继承ActiveRecord :: Base时会发生很多事情。在查看其他问题之前,我猜测Dog是一个rails ActiveRecord模型,你只是忘了添加

class Dog < ActiveRecord::Base

答案 1 :(得分:0)

如果你看顶部你有这个:

class Dog < ActiveRecord::Base

这会导致您的班级Dog继承自ActiveRecord::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时,您还会继承其初始化&#39;方法,所以你不必自己设置一个。 该类根据您为与该类匹配(通过铁路惯例)的表进行数据库迁移时设置的模式,知道要创建哪些属性方法。