为什么“create!do”在这个模型中起作用而不是“new!do”?

时间:2012-11-05 10:00:42

标签: ruby-on-rails

我有以下代码:

user.rb

  def self.create_with_omniauth(auth)
    create! do |user|
      user.provider = auth["provider"]
      user.uid = auth["uid"]
      user.name = auth["info"]["name"]
      # Add an error message when email is already taken
      user.email = auth["info"]["email"]
      user.password = user.password_confirmation = SecureRandom.urlsafe_base64(n=6) 
    end
  end

sessions_controller.rb:

 def omniauth_create
    auth = request.env["omniauth.auth"]
    user = User.from_omniauth(env["omniauth.auth"])
    if user.save
      sign_in user
      redirect_back_or user
    else
      #session[:omniauth] = request.env['omniauth.auth'].except('extra')
      redirect_to signup_path
      flash.now[:error] = 'Worked!'
    end
  end

现在这段代码不起作用,因为User模型中的create! do会保存用户,并且在执行到达控制器并通过if语句之前会抛出错误。所以我想到了使用new! do而是得到了这个:

undefined method `new!' for #<Class:0xb5aaf04>

为什么“创造!做”不是“新的!做”?

(我采取了错误的方法来解决这个问题?如果是这样,我可以应用其他解决方案吗?)

2 个答案:

答案 0 :(得分:2)

我认为没有new!方法,我只知道create!save!

newbuild只是初始化对象而不保存到数据库,save会这样做,create同时进行初始化和保存。

最后的爆炸是在发生错误而不是返回false时引发异常。

因此,如果您使用new,则必须save!才能保留记录。

  def self.create_with_omniauth(auth)
    pw = SecureRandom.urlsafe_base64(6) 
    record = new(
      provider: auth["provider"],
      uid: auth["uid"],
      name: auth["info"]["name"],
      # Add an error message when email is already taken
      email: auth["info"]["email"],
      password: pw,
      password_confirmation: pw
    )
    record.save!
  end

答案 1 :(得分:0)

您可以找到模型的方法,运行rails console并键入:ModelName.methods.sort