As we all begin transitioning to Rails 4.0 and strong_params
there are going to be a fair amount of changes to our gems and other integrations. Since the attr_accessible functionality no longer exists inside our models, we need to move this into the controllers that are responding to our web forms.
Devise, one of the common authentication gems, provides a reasonably easy way to accept extra fields as part of registration. The first thing we do is add the extra fields to the model in the database. I'm assuming you know how to add a migration to create these fields, so we will skip right updating the view.
Just as usual, we generate the Devise views by running rails g devise:views
. Hopping into app/views/devise/registrations/new.html.erb
we can add our extra fields. In this example I'm just going to show a snippet of the form fields I'm adding. I'm also using Formtastic to generate a lot of the HTML around the fields for Bootstrap automatically. Formtastic provides the semantic_form_for
and f.input
methods you see in this example.
<%= semantic_form_for(resource, :as => resource_name, :url => registration_path(resource_name), html: {class: "form-vertical"}) do |f| %>
<%= f.input :full_name %>
<%= f.input :phone %>
<%= f.input :email %>
<%= f.input :password %>
<%= f.input :password_confirmation %>
<% end %>
You can also write regular f.text_field
fields and a regular form_for
, we just need to make sure that the fields are rendering on the page. Now when you submit this, it is going to send over the data but those fields won't be permitted so your users will be missing data that was submitted.
Devise allows you to override the strong_params implementation from the ApplicationController pretty easily. The idea is that you put it into a before_filter
to check to see if the current controller processing the request is one from Devise. If it is, then we override the parameters that are allowed.
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_filter :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:email, :password, :password_confirmation, :full_name, :phone) }
end
end
And surprisingly, that's all you have to do. Adding a couple lines into your application_controller.rb
isn't such a bad thing and it certainly makes for a more flexible and secure implementation than attr_accessible did. That's all for today!
Want to learn more about Devise? Check out the Rails Gems Foundation Course