Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialRyan Trimble
15,559 PointsRuby Issues
Greetings!
I am running into an issue where it appears first_name, last_name, and profile_name are not getting entered into the database.
When I go into the rails console I see:
User id: 1, first_name: nil, last_name: nil, profile_name: nil, email: m******2@gmail.com, encrypted_password: $2a$10$DiQMxpa3f2aiaAF58JQNaO9AuhRvSdb4tNjxX9eF78R9..., reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 1, current_sign_in_at: "2014-03-27 02:42:39, last_sign_in_at: 2014-03-27 02:42:39, current_sign_in_ip: 127.0.0.1, last_sign_in_ip: 127.0.0.1, created_at: 2014-03-27 02:42:39, updated_at: 2014-03-27 02:42:39
For the record, I am using Rails 4.0.4 and have run into the issue where attr_accessible is deprecated. I fixed this by adding protected_attributes to the Gemfile. I'm a little unsure why these items are not getting added to the database.
Here is my migrate file:
class DeviseCreateUsers < ActiveRecord::Migration
def change
create_table(:users) do |t|
## Database authenticatable
t.string :first_name,
t.string :last_name,
t.string :profile_name,
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
## Recoverable
t.string :reset_password_token
t.datetime :reset_password_sent_at
## Rememberable
t.datetime :remember_created_at
## Trackable
t.integer :sign_in_count, default: 0, null: false
t.datetime :current_sign_in_at
t.datetime :last_sign_in_at
t.string :current_sign_in_ip
t.string :last_sign_in_ip
## Confirmable
# t.string :confirmation_token
# t.datetime :confirmed_at
# t.datetime :confirmation_sent_at
# t.string :unconfirmed_email # Only if using reconfirmable
## Lockable
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
# t.string :unlock_token # Only if unlock strategy is :email or :both
# t.datetime :locked_at
t.timestamps
end
add_index :users, :email, unique: true
add_index :users, :reset_password_token, unique: true
end
end
Here is my views/devise/registration/new.html.erb file:
<h2>Sign up</h2>
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= devise_error_messages! %>
<div class="form-group">
<%= f.label :first_name %><br />
<%= f.text_field :first_name, placeholder:"Enter First Name", class:"form_control" %>
</div>
<div class="form-group">
<%= f.label :last_name %><br />
<%= f.text_field :last_name, placeholder:"Enter Last Name", class:"form_control" %>
</div>
<div class="form-group">
<%= f.label :profile_name %><br />
<%= f.text_field :profile_name, placeholder:"Enter Profile Name", class:"form_control" %>
</div>
<div class="form-group">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: false, placeholder:"Enter Email", class:"form_control" %>
</div>
<div class="form-group">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "off", placeholder:"Enter Password", class:"form_control" %>
</div>
<div class="form-group">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "off", placeholder:"Retype Password", class:"form_control" %>
</div>
<div class="form-group">
<%= f.submit "Sign up", class:"btn btn-primary" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
and here is my user.rb model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me,
:first_name, :last_name, :profile_name
def full_name
first_name + " " + last_name
end
end
If you need any further information please let me know, I am really trying to figure this out and make it work!
Also, sorry if I botched the markdown on this post, I tried fixing it several times, but I cannot seem to make it work correctly :-/
4 Answers
Brandon Barrette
20,485 PointsSo that error has nothing to do with the user in the database (although it appears that way)
You are getting the error because there is no user_id stored with your status. So what's happening is:
@status.user = nil #no idea, since there is no user_id in the db
Then when you call
@status.user.full_name
You are calling full_name on nil, so it won't work. My guess is in your statuses_controller, you need to add user_id to the protected attributes, much like you just added first_name, last_name etc to the users_controller. This way, when you save a status, the user_id will be permitted through and then be saved in the db.
To check this you can go to rails console in the terminal and type
Status.last
Look and see if the user_id is stored there or not.
Brandon Barrette
20,485 PointsThis has been answered a few times on the forums. It's an issue with Rails 4 and protected_attributes. Here's one solution. I'd scour the forum a bit more for other solutions.
https://teamtreehouse.com/forum/treebook-app-firstname-lastname-profilename-nat-saving
Ryan Trimble
15,559 PointsOK! I tried that, and I do appear to be getting entries for first_name, last_name, and profile_name in the database now!
I am, however, still getting the NoMethodError that reads
undefined method `first_name' for nil:NilClass
Even after reseting the database and running rake db:migrate. There is only one entry in the DB and it definitely has the First Name, Last Name, etc.
I will continue looking, thanks for your assistance on this one!
Ryan Trimble
15,559 PointsNow, I have it working... but only on the show page, on the index page it does not show the full name!
On the Show page, I have it set up like this:
<p>
<strong>Name: <%= @status.user.full_name %></strong>
</p>
And on the index page:
<% @statuses.each do |status| %>
<div class="status">
<strong><% status.user.full_name %></strong>
<p><%= status.content %></p>
I now know that I at least have the correct information in the database and it is working... just not everywhere.
Ryan Trimble
15,559 PointsOH WAIT!
I saw it as I was re-reading my comment. I missed and equal's sign in the erb opening on the index page.
<% status.user.full_name %>
should be
<%= status.user.full_name %>
AND NOW IT IS WORKING!
THANKS SO MUCH FOR ALL OF YOUR ASSISTANCE!
Brandon Barrette
20,485 PointsSo for sanity sake, here is the difference between <%= and <%
<%= #display the output when between this %>
<% #run this code, don't display the output %>
Ryan Trimble
15,559 PointsThat is a very useful tip! Thanks again!
Ryan Trimble
15,559 PointsRyan Trimble
15,559 PointsI literally just discovered this after replying to your first comment. The user_id is not getting recorded on the status table! I still wasn't sure how to fix it, but I'm sort of happy that I was able to determine that was the problem.
I'm on my way to dinner right now, but I will be checking out what you suggested when I get back.
Thanks for all your help!!