Related
I was setting up Devise & Omniauth as per railscasts like I usually do, only now I'm using Rails 5.0.1 and ruby 2.3.3
When I go to add a user, not even using Omniauth, just using a basic email + password + confirmation the page reloads with an error of "Email can't be blank". I can see the parameters include the email.
I used Pry to investigate - things get weird here.
[1] pry(#<RegistrationsController>)> params
=> <ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"[removed this!]", "user"=><ActionController::Parameters {"email"=>"test#test.com", "password"=>"testtest", "password_confirmation"=>"testtest"} permitted: false>, "commit"=>"Sign up", "controller"=>"registrations", "action"=>"create"} permitted: false>
[3] pry(#<RegistrationsController>)> #user
=> #<User id: nil, email: "test#test.com", created_at: nil, updated_at: nil, first_name: nil, last_name: nil, image_url: nil, headline: nil, dob: nil, gender: nil, webpage_url: nil, twitter: nil, linkedin: nil, blog_url: nil, description: nil, country: nil, state: nil, city: nil, phone: nil, full_bio: nil, profile_claimed: nil>
[4] pry(#<RegistrationsController>)> #user.class
=> User(id: integer, email: string, encrypted_password: string, reset_password_token: string, reset_password_sent_at: datetime, remember_created_at: datetime, sign_in_count: integer, current_sign_in_at: datetime, last_sign_in_at: datetime, current_sign_in_ip: string, last_sign_in_ip: string, created_at: datetime, updated_at: datetime, first_name: string, last_name: string, image_url: string, headline: string, dob: date, gender: string, webpage_url: string, twitter: string, linkedin: string, blog_url: string, description: text, country: string, state: string, city: string, phone: string, full_bio: text, type: string, profile_claimed: boolean)
[5] pry(#<RegistrationsController>)> #user.email
=> nil
[7] pry(#<RegistrationsController>)> #user.errors
=> #<ActiveModel::Errors:0x007f9de2c82da0
#base=
#<User id: nil, email: "test#test.com", created_at: nil, updated_at: nil, first_name: nil, last_name: nil, image_url: nil, headline: nil, dob: nil, gender: nil, webpage_url: nil, twitter: nil, linkedin: nil, blog_url: nil, description: nil, country: nil, state: nil, city: nil, phone: nil, full_bio: nil, profile_claimed: nil>,
#details={:email=>[{:error=>:blank}, {:error=>:blank}]},
#messages={:email=>["can't be blank"], :password=>[], :password_confirmation=>[]}>
[8] pry(#<RegistrationsController>)> #user.email.class
=> NilClass
You can see that if I access #user it returns the hash containing the email. However if I try #user.email I get nil. And when I ask for #user.errors the message says email can't be blank.
I've been hunting a while on this one. Thanks in advance for any help!
--
class ApplicationController < ActionController::Base
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:email])
end
end
Puma server.
Started POST "/users" for ::1 at 2017-01-07 20:42:57 -0500
Processing by RegistrationsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"tfBeZtXEFdZV9Rx3dJgCQJ+9hHuvgFcbc3dD9D7Q6yKki4GmlVw17/qlDm2squ3hKngX3Juu12iaM1Dki9qXig==", "user"=>{"email"=>"test#test.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
(0.1ms) begin transaction
(0.1ms) rollback transaction
Rendering registrations/new.html.erb within layouts/application
Rendered devise/shared/_links.html.erb (0.7ms)
Rendered registrations/new.html.erb within layouts/application (4.6ms)
--
rails console
Running via Spring preloader in process 12578
Loading development environment (Rails 5.0.1)
2.3.3 :001 > u = User.new
=> #<User id: nil, email: "", created_at: nil, updated_at: nil, first_name: nil, last_name: nil, image_url: nil, headline: nil, dob: nil, gender: nil, webpage_url: nil, twitter: nil, linkedin: nil, blog_url: nil, description: nil, country: nil, state: nil, city: nil, phone: nil, full_bio: nil, profile_claimed: nil>
2.3.3 :002 > u.email = "test#test.com"
=> "test#test.com"
2.3.3 :003 > u.password = "password"
=> "password"
2.3.3 :004 > u.password_confirmation = "password"
=> "password"
2.3.3 :005 > u.save
(0.2ms) begin transaction
(0.1ms) rollback transaction
=> false
2.3.3 :006 > u.errors
=> #<ActiveModel::Errors:0x007f87163eeac8 #base=#<User id: nil, email: "test#test.com", created_at: nil, updated_at: nil, first_name: nil, last_name: nil, image_url: nil, headline: nil, dob: nil, gender: nil, webpage_url: nil, twitter: nil, linkedin: nil, blog_url: nil, description: nil, country: nil, state: nil, city: nil, phone: nil, full_bio: nil, profile_claimed: nil>, #messages={:email=>["can't be blank"]}, #details={:email=>[{:error=>:blank}, {:error=>:blank}]}>
I believe permitted: false says that your parameters are not permitted and can't be saved. Did you set up strong parameters for Users controller?
I am trying to test the following controller action(Using Ruby on Rails, RSPEC, and FactoryGirl):
class ContactsController < ApplicationController
before_action :authenticate_user!
def index
#contacts = current_user.contacts
# #contacts = Contact.all
end
Here is my contacts_controller_spec.rb file:
require 'rails_helper'
describe ContactsController do
before do
#user = FactoryGirl.create(:user_with_contacts)
sign_in #user
end
describe "GET INDEX" do
it "assigns #contacts" do
expect(assigns(:contacts)).to eq(#user.contacts)
end
end
Failure/Error: expect(assigns(:contact)).to eq([contact])
expected: [#<Contact id: 295, first_name: "Loy", email: "leon#hegmannhintz.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Wyman", user_id: 343>]
got: #<Contact id: nil, first_name: nil, email: nil, phone_number: nil, created_at: nil, updated_at: nil, last_name: nil, user_id: nil>
And here is my users_spec.rb file:
FactoryGirl.define do
factory :user do
email { Faker::Internet.email }
password { "32423fdsfasf42" }
factory :user_with_contacts do
transient do
contacts_count 2
end
after(:create) do |user, evaluator|
create_list(:contact, evaluator.contacts_count, user: user)
end
end
end
end
Any Help please? I have been stuck on this for a long time.
If i call
puts #user.inspect
I get
#<User id: 340, email: "johnson_kaulke#brekke.com", encrypted_password: "$2a$04$Si5k6Q1eYERvhQITXKBoIOGEzPyK50E3IQ.yjRcqmDj...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42">
and
calling
puts #user.contacts.inspect
I get
#<ActiveRecord::Associations::CollectionProxy [#<Contact id: 289, first_name: "Fae", email: "ariane#johnston.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Spinka", user_id: 340>, #<Contact id: 290, first_name: "Marcellus", email: "chloe_deckow#buckridge.net", phone_number: "6044339393", created_at: "2015-09-12 19:13:42", updated_at: "2015-09-12 19:13:42", last_name: "Bashirian", user_id: 340>]>
Its just when i call the assigns(:contacts) that the problem happens!
I think you forgot to invoke the controller action. :)
Try adding get :index
it "assigns #contacts" do
get :index
expect(assigns(:contacts)).to eq(#user.contacts)
end
Scenario: Show email in landing page when you click on password reset link
Given I am a user and I clicked on the password reset link inside my email
Then I am redirected to 'Change Password' page
And I see two password fields
Expected I also see the email of the user whose password is to be reset
Problem: How to get the email from only the :reset_password_token value?
Output from console when I binding.pry in the view /views/devise/passwords/edit.html.erb
[1] pry(#<#<Class:0x007fd4ec6f65f8>>)> resource
=> #<User id: nil, email: "", encrypted_password: "", reset_password_token: "Ba-9txxmmUMkU_xywypz", reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil, updated_at: nil, first_name: nil, last_name: nil, customer_admin_id: nil, admin_id: nil, confirmation_token: nil, confirmed_at: nil, confirmation_sent_at: nil, organization_id: nil, status: nil, middle_name: nil, type: nil, cell_number: nil, phone_number: nil, extension: nil>
also When I invoke User.find(5) I see
#<User id: 5, email: "recruiter_one+org_one#mysite.com", encrypted_password: "$2a$10$v7gYTdfoIZ9yCVIx3Xb5lOYVPly71NHtOc1mbWuHxZvt...", reset_password_token: "095a18fc2455c39e4838c322e3124d0052cf2cc0e86b7fe3486...", reset_password_sent_at: "2015-06-29 10:01:56", remember_created_at: nil, sign_in_count: 10, current_sign_in_at: "2015-06-29 10:01:04", last_sign_in_at: "2015-06-29 09:35:56", current_sign_in_ip: "192.164.79.122", last_sign_in_ip: "192.164.79.122", created_at: "2015-06-12 05:06:50", updated_at: "2015-06-29 10:01:56", first_name: "Rec One Loc One", last_name: "Peter", customer_admin_id: nil, admin_id: nil, confirmation_token: nil, confirmed_at: "2015-06-12 05:13:49", confirmation_sent_at: "2015-06-12 05:06:50", organization_id: 3, status: "active", middle_name: "", type: nil, cell_number: "", phone_number: "1231232131", extension: "">
That is:
[4] pry(#<#<Class:0x007fd4ec6f65f8>>)> User.find(5).reset_password_token
CACHE (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 5 LIMIT 1 [["id", 5]]
=> "095a18fc2455c39e4838c322e3124d0052cf2cc0e86b7fe3486f72a67c5a5315"
[5] pry(#<#<Class:0x007fd4ec6f65f8>>)>
095a18fc2455c39e4838c322e3124d0052cf2cc0e86b7fe3486f72a67c5a5315 from database does not match with Ba-9txxmmUMkU_xywypz I get from resource
PS: I use devise (3.2.4)
You should get digest from password_reset_token by
digiest = Devise.token_generator.digest(self, :reset_password_token, original_token)
where original_token is Ba-9txxmmUMkU_xywypz
Next, You can find resource by
user = User.find_by_reset_password_token(digiest)
Also, You should override password_controller#edit, and define #email variable
class PasswordsController < Devise::PasswordsController
# GET /resource/password/edit?reset_password_token=abcdef
def edit
digiest = Devise.token_generator.digest(resource_class, :reset_password_token, params[:reset_password_token])
#email = resource_class.find_by_reset_password_token(digiest).email
self.resource = resource_class.new
set_minimum_password_length
resource.reset_password_token = params[:reset_password_token]
end
end
in routes.rb
devise_for :users,
:controllers => {
:passwords => 'passwords'
}
For the latest version of devise (>= v3.3.0), you could simply use the method given by devise with_reset_password_token(:token)
User.with_reset_password_token('sxZo2fk8hux6hKyufpCx')
This will return the user if exists or returns nil.
You also would want to override the edit method of Devise::PasswordsController, or for the simplest use, keep the above code in a helper.
I would like to edit a supplier name in my heroku database. I'm having trouble accessing the name attribute:
irb(main):015:0> Supplier.where(:name => "Test")
=> #<ActiveRecord::Relation [#<Supplier id: 3070, name: "Test", email: "test#me.com", phone: "555555", website: "http://www.test.co.uk", region_id: 3, category_id: 8, created_at: "2015-02-20 13:28:59", updated_at: "2015-02-20 13:28:59", rating: 0.0, address: nil, facebook_url: nil, twitter_url: nil, google_url: nil, video_url: nil, slug: "test", logo_url: nil, image_one_url: nil, image_two_url: nil, image_three_url: nil, image_four_url: nil, description: nil, reviews_count: 0, source: nil, source_other: nil>]>
irb(main):016:0> _.name
=> "Supplier"
I'm not clear why _.name is resulting in "Supplier" rather than "Test".
Can anyone tell me what I'm missing?
Supplier.where(:name => "Test") returns multiple records. Use
supplier = Supplier.where(:name => "Test").first
supplier.name
How can I delete or destroy an object located in memory, but not in the database?
irb(main):034:0> mentor.registered_students.build(:user_id => 20)
=> #<RegisteredStudent id: nil, user_id: 20, assigned_mentor_id: 1, description: nil, created_at: nil, updated_at: nil>
irb(main):035:0> mentor.registered_students.last
=> #<RegisteredStudent id: nil, user_id: 20, assigned_mentor_id: 1, description: nil, created_at: nil, updated_at: nil>
irb(main):036:0> mentor.registered_students.last.destroy
(0.3ms) BEGIN
(0.2ms) COMMIT
=> #<RegisteredStudent id: nil, user_id: 20, assigned_mentor_id: 1, description: nil, created_at: nil, updated_at: nil>
irb(main):037:0> mentor.registered_students.last.delete
=> #<RegisteredStudent id: nil, user_id: 20, assigned_mentor_id: 1, description: nil, created_at: nil, updated_at: nil>
irb(main):038:0> mentor.registered_students.last
=> #<RegisteredStudent id: nil, user_id: 20, assigned_mentor_id: 1, description: nil, created_at: nil, updated_at: nil>
I already used destroy or delete but they look for records in database.
CONTROLER ACTION:
def mix
unless params[:mentor_id].nil? || params[:students_id].nil?
#mentor = AssignedMentor.find params[:mentor_id]
#students = params[:students_id]
#students.each do |student|
if student[1] == "0"
registered_student = RegisteredStudent.where("assigned_mentor_id = ? AND user_id = ?", #mentor.id, student[0] ).first
registered_student.destroy
end
if student[1] == "1"
#mentor.registered_students.build(:user_id => student[0])
#mentor.save
if #mentor.errors.size > 0
#mentor.registered_students.reload
end
end
end
#redirect_to bind_admin_users_path
end
#flash[:alert] = t("labels.no_students")
redirect_to bind_admin_users_path
end
mentor.registered_students.reload
does the trick