I have a user model and a profile model.
The associations are:
user has_one :profile
profile belongs_to :user
I have a user model which I am trying to use to create a profile when a new user is first created. I only want to run this method if the user is new.
I have this callback method in user.rb:
after_create :build_profile
def build_profile
Profile.create(user: self) # Associations must be defined correctly for this syntax, avoids using ID's directly.
# Profile.save
end
When I save this and go through my authentication process (using devise & omniauth), I get this runtime error:
RuntimeError (Could not find a valid mapping for [#<User id: 1, first_name: "Me", last_name: "Ma", email: "me#gmail.com", encrypted_password: "$2a$10$KCZn..HS2GuGjvlcNtfAH/28.DQoWetO...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 16, current_sign_in_at: "2015-12-15 09:57:14", last_sign_in_at: "2015-12-15 09:27:07", current_sign_in_ip: #<IPAddr: IPv4:49, last_sign_in_ip: #<IPAddr: IPv4:49.195>, confirmation_token: nil, confirmed_at: "2015-12-15 09:02:58", confirmation_sent_at: "2015-12-15 08:42:48", unconfirmed_email: nil, failed_attempts: 0, unlock_token: nil, locked_at: nil, created_at: "2015-12-09 23:53:20", updated_at: "2015-12-15 09:57:14", image: nil>, #<Profile id: 1, user_id: 1, title: nil, hero_image: nil, overview: nil, occupation: nil, external_profile: nil, working_languages: nil, created_at: "2015-12-18 21:58:49", updated_at: "2015-12-18 21:58:49">]):
I'm not sure what this mapping error means.
I have a user_id integer in my profiles table and it seems to be referencing the relevant user id properly.
I tried adding profile.save to the build_profile method, but the same error is generated, so I don't thing that helps.
Can anyone see what's going wrong?
Related
Kind of an odd bug I am running into. Working on upgrading a Rails app from 3.2.22.1 tp 4.2.11.3. Everything is working pretty well. Test suite is passing on green. However when I go into the rails console and do user = User.new or list the attributes using User.new.attributes I am only getting a few of the fields returned.
Specifically
{"_id"=>BSON::ObjectId('XXxxXXxxxxXXXxXX'),
"email"=>"",
"encrypted_password"=>"",
"sign_in_count"=>0,
"time_zone"=>"Central Time (US & Canada)",
"admin"=>false}
This list should be much larger, for example, it is excluding all Devise fields like last_sign_in_at or any of them. Here is what it looks like, the same command, run on our production server which is the previous version of rails
_id: xxxXXXxxxXXXXxXXXXxx,
invited_by_type: nil,
invited_by_field: nil,
invited_by_id: nil,
email: "",
encrypted_password: "",
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,
confirmation_token: nil,
confirmed_at: nil,
confirmation_sent_at: nil,
unconfirmed_email: nil,
invitation_token: nil,
invitation_created_at: nil,
invitation_sent_at: nil,
invitation_accepted_at: nil,
invitation_limit: nil,
name: nil,
time_zone: "Central Time (US & Canada)",
admin: false
I am worried that there is something failing silently and I am not detecting it. I can save the unlisted values in the console, but it does not show them to me, which is not how it worked previously.
Anyone understand why this is happening?
specific versions are:
mongid -> 5.0.1
devise -> 4.7.2
Rails -> 4.2.11.3
Latest version of Mongoid does not include attributes that were never written in attributes.
Unless you have references to documentation that claims that Mongoid would return attributes that were never written, you are experiencing expected behavior.
This is a weird question... The context is that somehow, my program keeps creating weird arbitrary blank users with no information. I'm trying to debug it because it's certainly annoying but I don't want it to have some potentially other problems.
I'd like to debug it by figuring out when these random blank users were created and then looking at the logs with that time stamp. Unfortunately the user looks like this:
#<User id: 175, email: "", created_at: nil, updated_at: nil, encrypted_password: "", 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, confirmation_token: nil, confirmed_at: nil, confirmation_sent_at: nil, unconfirmed_email: nil, failed_attempts: 0, unlock_token: nil, locked_at: nil, stripe_customer_id: nil, stripe_card_id: nil, invite_code: nil, invited_by: nil, profile_pic: nil, first_name: nil, last_name: nil, full_name: nil>
I didn't realize it was possible to have this happen (creation without created_at), so am curious to see what could lead to this, and maybe that will help the debugging.
FYI I have tried to just look at my log over a long time period but the weird thing is I definitely do NOT see the actual create action being called so many times. I even have a puts statement right after the create just to catch this and it has only been logged twice (the appropriate amount). FWIW I'm using Devise.
Thanks
This question already has answers here:
What's the difference between Ruby's dup and clone methods?
(6 answers)
Closed 7 years ago.
I need to know the difference between Rails dup and clone methods, because dup duplicates the id attribute and clone doesn't:
juan:~/alhambra$ rails c
Loading development environment (Rails 3.0.1)
1.9.3-p551 :001 > #user=User.last
=> #<User id: 2, email: "ferbad12#hotmail.com", encrypted_password: "$2a$10$/Fsz8DZ9PQbReTU1.wyxS.m3IOxZSV3siKDrrtUJdupz...", password_salt: "$2a$10$/Fsz8DZ9PQbReTU1.wyxS.", reset_password_token: nil, remember_token: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2015-05-06 23:34:20", last_sign_in_at: "2015-05-06 23:34:20", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", created_at: "2015-05-06 23:33:37", updated_at: "2015-05-06 23:34:20">
1.9.3-p551 :002 > #user.clone
=> #<User id: nil, email: "ferbad12#hotmail.com", encrypted_password: "$2a$10$/Fsz8DZ9PQbReTU1.wyxS.m3IOxZSV3siKDrrtUJdupz...", password_salt: "$2a$10$/Fsz8DZ9PQbReTU1.wyxS.", reset_password_token: nil, remember_token: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2015-05-06 23:34:20", last_sign_in_at: "2015-05-06 23:34:20", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", created_at: "2015-05-06 23:33:37", updated_at: "2015-05-06 23:34:20">
1.9.3-p551 :003 > #user.dup
=> #<User id: 2, email: "ferbad12#hotmail.com", encrypted_password: "$2a$10$/Fsz8DZ9PQbReTU1.wyxS.m3IOxZSV3siKDrrtUJdupz...", password_salt: "$2a$10$/Fsz8DZ9PQbReTU1.wyxS.", reset_password_token: nil, remember_token: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2015-05-06 23:34:20", last_sign_in_at: "2015-05-06 23:34:20", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", created_at: "2015-05-06 23:33:37", updated_at: "2015-05-06 23:34:20">
In rails 3.0, dup and clone performed essentially opposite roles as to what they do now. From ActiveRecord::Base:
Cloned objects have no id assigned and are treated as new records. Note that this is a "shallow" clone as it copies the object's attributes only, not its associations. The extent of a "deep" clone is application specific and is therefore left to the application to implement according to its need.
While it can be seen in the same file that dup simple copied the record and its attributes:
def dup
obj = super
obj.instance_variable_set('#attributes', #attributes.dup)
obj
end
This differs from current rails 4, which defines dup and clone to more follow the note from the ruby docs, noted in a similar question not specific to rails.
In general, clone and dup may have different semantics in descendent classes. While clone is used to duplicate an object, including its internal state, dup typically uses the class of the descendent object to create the new instance.
As can be seen from the from the more current ActiveRecord source:
##
# :method: clone
# Identical to Ruby's clone method. This is a "shallow" copy. Be
# warned that your attributes are not copied. That means that modifying
# attributes of the clone will modify the original, since they will both
# point to the same attributes hash. If you need a copy of your attributes
# hash, please use the #dup method.
#
# user = User.first
# new_user = user.clone
# user.name # => "Bob"
# new_user.name = "Joe"
# user.name # => "Joe"
#
# user.object_id == new_user.object_id # => false
# user.name.object_id == new_user.name.object_id # => true
#
# user.name.object_id == user.dup.name.object_id # => false
##
# :method: dup
# Duped objects have no id assigned and are treated as new records. Note
# that this is a "shallow" copy as it copies the object's attributes
# only, not its associations. The extent of a "deep" copy is application
# specific and is therefore left to the application to implement according
# to its need.
# The dup method does not preserve the timestamps (created|updated)_(at|on).
The tutorial explains this, everything opposite what my console displays
p1 = Post.create(title: 'Post 1', message: 'Amazing message')
p3 = p1.clone
p3.title = "This is now p3"
p1 #=> #<Post id: 1, title: "Post 1", message: "Amazing message", created_at: "2014-07-01 19:45:44", updated_at: "2014-07-01 19:45:44">
p3 #=> #<Post id: nil, title: "This is now P3", message: "Amazing message", created_at: nil, updated_at: nil>
I'm attempting to seed my database using the data that I grabbed with the seed_dump gem, found here. Anyway, the seed file generated looks legit, but it seems to be falling afoul of the user model validation:
ActiveRecord::RecordInvalid: Validation failed: Password can't be blank
To give an idea the seed looks like this:
User.create!([
{email: "1234#localhost", encrypted_password: "$2a$10$5eoHh6M2q4GjGkHClO.NqebWWhS94D8rNj5Ot6CB2qrbn7IrTfkSa", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2014-12-31 22:27:09", last_sign_in_at: "2014-12-31 22:27:09", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", admin: false}
])
Also, I'm using the devise gem for users management.
Is there an elegant way to seed the user data given this filter?
You can do:
u = User.new([
{email: "1234#localhost", encrypted_password: "$2a$10$5eoHh6M2q4GjGkHClO.NqebWWhS94D8rNj5Ot6CB2qrbn7IrTfkSa", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2014-12-31 22:27:09", last_sign_in_at: "2014-12-31 22:27:09", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", admin: false}
])
u.save!(validate: false)
Had the same issue. The User.new solution did not work for me.
The following solution did work, from similar question on "Seeding Users with Devise" here:
Seeding users with Devise in Ruby on Rails
In short, replace the encrypted_password with password and a plain text password you are comfortable using.
Example:
User.create!([
{email: "1234#localhost", password: "some_password", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2014-12-31 22:27:09", last_sign_in_at: "2014-12-31 22:27:09", current_sign_in_ip: "127.0.0.1", last_sign_in_ip: "127.0.0.1", admin: false}
])
You can then run rake db:seed. Rails will do its magic (by automatically creating the encrypted_password hash) for each user, and you will be able to login normally.
This is my EmailContact model:
class EmailContact < ActiveRecord::Base
validates :email, :presence => true, :email => true
end
I am using the ruby gem valid_email.
I run the following in my rails console, in the same environment as my rake task I will show later:
>> email_contact = EmailContact.new(:email => 'a253545#gmail.com')
>> email_contact.valid?
true
So, as you can see, in the rails console I am building an EmailContact and it is valid.
Then I run this in my rake task:
list_entity = {:branch=>"Nashua Branch-YMCA of Greater Nashua", :branch_id=>"485", :call_type=>nil, :client_id=>"2264", :client_name=>"YMCA of Greater Nashua", :date_of_birth=>nil, :email=>"a253545#gmail.com", :first_name=>"Sridhar", :last_name=>"Tipirneni", :list_entity_id=>"277795", :mem_id=>"4085008", :mem_unit_id=>"2138728", :member_id=>"0213262-01", :membership_type=>"Dual 2 Adult Family", :membership_type_id=>"5203", :most_recent_join_date=>nil, :old_membership_type=>nil, :phone_number=>"(970)456-1010", :primary_language=>"English", :termination_date=>nil, :termination_reason=>nil, :unit_id=>"0213262", :unit_type=>nil, :visits=>nil, :"#i:type"=>"c:NpsListEntityDto"}
email_contact = EmailContact.new(list_entity.except(:"#i:type"))
puts email_contact.valid?
This returns false. The only validation, at all, is the email. Why does this email validate successfully in my console but fail in my rake task?
FYI, when I remove :email => true from my EmailContact model and only validate the presence of an :email, they both work fine. So the issue is definitely within the :email => true piece of my validation, but I don't understand why it passes in one place and fails in another.
EDIT
In my console, my model looks like this when using the full list_entity:
#<EmailContact id: nil, branch: "Nashua Branch-YMCA of Greater Nashua", branch_id: 485, call_type: nil, client_id: 2264, client_name: "YMCA of Greater Nashua", date_of_birth: nil, email: "a253545#gmail.com", first_name: "Sridhar", last_name: "Tipirneni", list_entity_id: 277795, mem_id: "4085008", mem_unit_id: "2138728", member_id: "0213262-01", membership_type: "Dual 2 Adult Family", membership_type_id: 5203, most_recent_join_date: nil, old_membership_type: nil, phone_number: "(970)456-1010", primary_language: "English", termination_date: nil, termination_reason: nil, unit_id: "0213262", visits: nil, loaded_at: nil, failed_at: nil, unit_type: nil, created_at: nil, updated_at: nil, list_id: nil>
In my rake task, when I run email_contact.inspect, this is returned:
#<EmailContact id: nil, branch: "Nashua Branch-YMCA of Greater Nashua", branch_id: 485, call_type: nil, client_id: 2264, client_name: "YMCA of Greater Nashua", date_of_birth: nil, email: "a253545#gmail.com", first_name: "Sridhar", last_name: "Tipirneni", list_entity_id: 277795, mem_id: "4085008", mem_unit_id: "2138728", member_id: "0213262-01", membership_type: "Dual 2 Adult Family", membership_type_id: 5203, most_recent_join_date: nil, old_membership_type: nil, phone_number: "(970)456-1010", primary_language: "English", termination_date: nil, termination_reason: nil, unit_id: "0213262", visits: nil, loaded_at: nil, failed_at: nil, unit_type: nil, created_at: nil, updated_at: nil, list_id: nil>
As you can see, they are both the exact same - The console model is valid, the rake model is invalid.
EDIT 2
I am using the valid_email gem, mentioned above. Here is the filepath:
/Users/luigi/.rvm/gems/ruby-2.0.0-p247#hub/gems/valid_email-0.0.4/lib/valid_email/email_validator.rb
All of my other gems are stored here as well it seems like.
It may also be worth mentioning that I get this warning before the validation fails:
[deprecated] I18n.enforce_available_locales will default to true in
the future. If you really want to skip validation of your locale you
can set I18n.enforce_available_locales = false to avoid this message.
20 hours later, I found the issue.
Using savon, all of the strings returned in my hash were being converted to a datatype of Nori::StringWithAttributes. The encoding was the same (UTF-8), but the class was different.
Running email_contact.email = email_contact.email.to_s prior to checking if the model is valid solves the issue.