wyc
wyc

Reputation: 55273

Why "create! do" works in this model and not "new! do"?

I have the following code:

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

Now this code doesn't work because create! do in the User model saves the user and an error is being thrown before the execution reaches the controller and pass through the if statement. So I thought of using new! do instead but got this:

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

Why "create! do" worked not "new! do"?

(I am taking the wrong approach to solve this? If so, what others solutions I can apply?)

Upvotes: 0

Views: 81

Answers (2)

Thanh
Thanh

Reputation: 8604

You can find what methods model has, run rails console and type: ModelName.methods.sort

Upvotes: 0

CodeOverload
CodeOverload

Reputation: 48475

I don't think there is a new! method, I'm only aware of create! and save!

new and build just initialize the object without saving to the db, save does, and create does both initialization and saving.

The bang at the end is to raise an exception if an error occured instead of returning false.

So if you use new you'll have to save! for the record to persist.

  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

Upvotes: 2

Related Questions