Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Ruby

Daniel Terreros
PLUS
Daniel Terreros
Courses Plus Student 6,178 Points

strong_parameters and treebook

Has anyone else been using rails 4.0.0 for treebook? I saw Jason wrote a strong_parameters blog entry, but I was curious how one would integrate that with the treebook rails app in the tutorials.

It's allowing me to create a profile despite first_name, last_name, profile_name, not being whitelisted...methinks I'm doing something wrong here.

The log agrees they aren't allowed, but still allows creation of the profile:

Unpermitted parameters: first_name, last_name, profile_name
[1m[35m (0.1ms)[0m  begin transaction
[1m[36mUser Exists (0.2ms)[0m  [1mSELECT 1 AS one FROM "users" WHERE "users"."email" =

31 Answers

Hello Daniel

Changing the devise sanitizer was one of two ways I've heard about ... I did it the other way, which is deriving from Devise::RegistrationsController and then altering the routes.rb.

From what I can remember of a thread on github's devise project nobody seemed bothered which way... I guess it will become clearer when more people move up to Rails 4.

app/controllers/users/registrations_controller.rb

class Users::RegistrationsController < Devise::RegistrationsController

  def sign_up_params
     params.require(:user).permit(:first_name, :last_name, :profile_name, :email, :password, :password_confirmation)
  end

end

routes.rb

devise_for :users, :controllers => {:registrations => "users/registrations"}

Rich

Daniel Terreros
PLUS
Daniel Terreros
Courses Plus Student 6,178 Points

Interesting, following the Customizing the parameters "The Lazy Way" I was able to get it to accept the parameters.

class ApplicationController < ActionController::Base
    before_filter :configure_permitted_parameters, if: :devise_controller?

    protect_from_forgery with: :exception

    protected

    def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:first_name, :last_name, :profile_name, 
                                                                                          :email, :password, :password_confirmation) }
    end
end

Is that correct? Is it secure?

Here is the log

"user"=>{"first_name"=>"danny", "last_name"=>"boy", "profile_name"=>"dboy",            "email"=>"danny@boy.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"},           "commit"=>"Sign up"}

Soooo problem solved?

Jonathan Seligsohn
Jonathan Seligsohn
23,116 Points

It seems like your code works! Thank you!

Robert Goddard
Robert Goddard
15,019 Points

I've found a lazy way to fix this issue:

Add these lines to the application_controller.rb:

before_filter :configure_permitted_parameters, if: :devise_controller?

Then in a protected section:

def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) << :first_name << :last_name << :profile_name
    devise_parameter_sanitizer.for(:account_update) << :first_name << :last_name << :profile_name
end

So the whole application_controller.rb should look like this:

class ApplicationController < ActionController::Base
  before_filter :configure_permitted_parameters, if: :devise_controller?
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  protected 

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) << :first_name << :last_name << :profile_name
    devise_parameter_sanitizer.for(:account_update) << :first_name << :last_name << :profile_name
  end
end

Note: This is from a fellow Rails 4 user who has just started to attempt learning rails and got stuck at this part of the tutorial. I think the best option would be to use their virtual machine that they provide with the rails 3.2 environment all set up, but it's kind neat to run into these problems and figure out how to fix them.

Here's where I got the idea: https://github.com/plataformatec/devise under the "Strong Parameters" section.

Yep! That's how it's done!

Great post!

AAAAAAWEEEEESOOOOOOMEEEEE! meaning, it worked :-)

Thank you so much!!! That worked perfectly!

oops

True...I kind of figured out what I am wanting to figure out, which is helpful, and this is what that is: I need to understand how to use the "strong parameters", which the RuntimeError "attr_accessibleis extracted out of Rails into a gem. Please use new recommended protection model for params(strong_parameters) or addprotected_attributes` to your Gemfile to use old one" is referring to. The only problem is that this requires updating more than just the attr_accessible stuff, as I understand. Quite a lot of things are linked to this problem. I tried adding $ gem 'protected_attributes' and then running $ bundle , but it didn't work.

Julia Schmidt
Julia Schmidt
1,244 Points

Hello, I'm using rails 4 for treebook too and got into a problem with the strong parameters in lesson 4.3 (Creating Relationships) which I can't seem to solve. Could someone of you tell me how I have to write the params to allow status to access the user_id ?

My error: undefined method `first_name' for nil:NilClass

Started PATCH "/statuses/7" for 127.0.0.1 at 2013-07-11 13:22:28 +0200 Processing by StatusesController#update as HTML Parameters: {"utf8"=>"?", "authenticity_token"=>"f2sznDwVQ8cFoykZ2Ntx9yQa2WYSJJQk51+nr0Ghe+w=", "status"=>{"user_id"=>"1", "content"=>"gadf"}, "commit"=>"Update Status", "id"=>"7"} Status Load (0.0ms) SELECT "statuses".* FROM "statuses" WHERE "statuses"."id" = ? LIMIT 1 [["id", "7"]] (1.0ms) begin transaction WARNING: Can't mass-assign protected attributes for Status: user_id app/controllers/statuses_controller.rb:44:in block in update' app/controllers/statuses_controller.rb:43:inupdate' (0.0ms) commit transaction Redirected to http://localhost:3000/statuses/7 Completed 302 Found in 44ms (ActiveRecord: 2.0ms)

Started GET "/statuses/7" for 127.0.0.1 at 2013-07-11 13:22:28 +0200 Processing by StatusesController#show as HTML ** Parameters: {"id"=>"7"}** Status Load (1.0ms) SELECT "statuses".* FROM "statuses" WHERE "statuses"."id" = ? LIMIT 1 [["id", "7"]] Rendered statuses/show.html.erb within layouts/application (3754.2ms) Completed 500 Internal Server Error in 3762ms

Code:

 <% @statuses.each do |status| %>
 <div class ="status">
 <strong>Name <%= status.user.first_name %></strong>
 <p><%= status.content %></p>
 <div class="meta">
 <%= link_to time_ago_in_words(status.created_at) + " ago", status%> 

I'm logged in, it's the right ID, cleared the databases... so it can only be the strong parameters I think.

The Application Controller has: protected

def configure_permitted_parameters
  devise_parameter_sanitizer.for(:sign_up) { |u|
    u.permit(:first_name, :last_name, :profile_name, :email, :password, :password_confirmation) }
end

also have in status controller the following

  # Never trust parameters from the scary internet, only allow the white list through.
  def status_params
     params.require(:status).permit(:name, :content, :user_id)
  end

def configure_permitted_parameters

  devise_parameter_sanitizer.for(:sign_up) { |u|
    u.permit(:first_name, :last_name, :profile_name, :email, :password, :password_confirmation) }

  devise_parameter_sanitizer.for(:statuses) { |u| u.permit(:user_id)}

end

I hope you can maybe help me here :) Thanks in advance

Julia Schmidt
Julia Schmidt
1,244 Points

Ok got it finally solved with your git Daniel :) thanks a bunch ! I had to add :user to attr_acessible in the status. I thought this wasn't neccessary because of params.

Jared Galanis
Jared Galanis
8,382 Points

Julia,

Can you tell me was it only :user you added to attr_accessible in the status.rb? Do you have anything in the user.rb under attr_accessible?

:(

Why the long face?

Hey I am trying to accomplish the same thing, it continues to give me the error NoMethodError in Statuses#index here is the code it speacks of

<% @statuses.each do |status| %> <div class="status"> <strong><%= status.user.first_name %></strong> <p><%= status.content %></p> <div class="meta"> <%= link_to time_ago_in_words(status.created_at) + "ago", status %>

i tried to do the tutorial in rails 3 but I had issues downgrading. im stuck trying to get rails 4 to work its giving me issues with attr_accessible. I need help bad.

sorry repost

well i have been stuck on the creating relationships part of the video for a while now any help would be greatly appreciated here is my git https://github.com/rashadmad/Ruby_on_rails_exercise.git git@github.com:rashadmad/Ruby_on_rails_exercise.git

please help Daniel Terreros can you please take a look at my repo. It seems like i had the same issue as you can you see if its an simple solution for it because i am out of options.

:(

Daniel Terreros
Daniel Terreros
Courses Plus Student 6,178 Points

I don't see any files in your github repo, so I can't help! If you get them up there, I would certainly try and help.

oh give me a sec i will fix that thank you for your time and reply

Here is my repo thank you for your patience https://github.com/rashadmad/BIB.git

Iskender Piyale-Sheard
Iskender Piyale-Sheard
2,172 Points

It seems the github repository for customizing the parameters "The Lazy Way", no longer exists. I'm having this problem using Rails 4 as well. Any links to a solution for this?

yeah no one replied so i took down my repo, What i did decide to do though is downgrade to rails 3 im still having issues but it helps to work on the same rails version as the video. Downgrading can actually be tricky. look for some ways of doing it online try it out if you cant downgrade message me here I will show you how i did it.

Iskender Piyale-Sheard
Iskender Piyale-Sheard
2,172 Points

Just figured it out. Thanks for not giving me the straight up answer. Forcing someone to figure it out always helps them learn it better. ^_^ Teach a man to fish right?

I ended up using:

gem uninstall rails gem uninstall railties

gem install rails --version 3.2.0 bundle

That worked for me (at least so far, I may run into some unexpected problems later I guess).

Thanks again!

Iskender Piyale-Sheard
Iskender Piyale-Sheard
2,172 Points

Yeah... scratch that... somehow it didn't work. hmm

your probably where im at now you got it downgraded but cant get attr_assebile to work with every thing else am i right?

have you found a way to move forward i have been at this for moths im starting to get really frustrated.

Iskender Piyale-Sheard
Iskender Piyale-Sheard
2,172 Points

Exactly my problem. I'm just going to start over. Not worth the effort. It's not that much work to go back and redo the steps. The seemingly longer way is sometimes the smarter, and often shorter way.

man i have started over a ton of times, what i would suggest if you do do that make sure (if you want to downgrade your rails and still use attr_accessible, make sure you use gem 'protected_attributes' in your gem file ) and please tell me how it went

Iskender Piyale-Sheard
Iskender Piyale-Sheard
2,172 Points

Hey Rashad,

I just started over and redid it from scratch after uninstalling and reinstalling rails (http://stackoverflow.com/questions/16909733/why-wont-rails-4-uninstall)

Now it works for me.

I've had my account paused for a few months while I've been studying other things, but I'd like to contribute what I can remember about this. I was able to correctly use Rails 4 and strong_paramaters, what I came to understand was that Rails 4 "strips" any parameters that are not whitelisted, so although your information will be processed, all parameters not whitelisted will appear simply as "Nil".

Sorry Rashad, I could see your emails in my inbox but wasn't able to reply on the forum. Might not be a bad feature to implement for paused accounts Treehouse? ;) If you would like further clarification Rashad let me know, I could take a look at your Github but I need to relearn it all myself first! :)

Jared Galanis
Jared Galanis
8,382 Points

Thomas, if you were able to whitelist the parameters needed and get things working why did you pause your account? Did you run into further problems using Rails 4 with this tutorial?

By the way I tried using the method referred to above, but I can't seem to get it work. Interestingly, I don't get the 'undefined method `first_name' for nil:NilClass' error, I just get no name next the "Name:" label on any of the pages.

Hi Jared, I've been preoccupied with other things and have had my account paused for quite some time, I don't remember much at all about what I was doing with Rails 4, but I absolutely did have it working fine with whitelisted parameters insofar as the stage I was at with the tutorial. I don't remember any specifics now, sorry!

well thanks for the reply any way, I have been trying many things, Bought a book on devise. Rolling authentication systems is quite complex. still learning but where ever i go its hard to find a solid tutorial on developing a devise auth system. But I have learned allot on my travels

this is a nightmare

this is a nightmare

this is a nightmare

jacob i know the vids out of date and it sucks to get so far and not be able to finish but, but some times you just need to put things on the back burner for a while, learn about other things that have to do with ruby on rails. They will probably have something up soon for ruby on rails four just be patient.

Jared Galanis
Jared Galanis
8,382 Points

Not sure if anyone here can help, but I'm another rails 4 user and I'm still getting the error "undefined method `first_name' for nil:NilClass". I have added the gem 'protected_attributes' to my gem file and have ran the bundle install command. I believe this is the relevant code that I'm using. Many thanks in advance for any help!

In application_controller.rb:

  def configure_permitted_parameters


    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:first_name, :last_name, :profile_name, :email, :password, :password_confirmation, :remember_me) }
    devise_parameter_sanitizer.for(:statuses) { |u| u.permit(:user_id, :first_name)}

  end

I've also tried the following in application_controller in place of the above:

  def configure_permitted_parameters
   devise_parameter_sanitizer.for(:sign_up) << :first_name << :last_name << :profile_name
   devise_parameter_sanitizer.for(:account_update) << :first_name << :last_name << :profile_name

 end

In statuses_controller.rb:

#Never trust parameters from the scary internet, only allow the white list through.
    def status_params
      params.require(:status).permit(:name, :content, :user_id)
    end

In status.rb:

attr_accessible :content, :user_id, :user

In user.rb:

attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :profile_name