I'm having an issue with new user registrations, and I've spent the last week searching for an answer. I noticed the issue when I was attempting to add Omniauth to my Rails app, starting off with just Github. After a user signs in with Github, they go to the regular devise signup page to answer a couple more questions before signing in. I am able to successfully create a new user, however when I look at the db, it shows both university_id and program_id as null. When I looked at the server logs, I noticed a Unpermitted parameters: code, university_id, program_id
error. I don't believe Omniauth has anything to do with this error per se since it's happening whether or not they choose to sign in with Github first. My suspicion is that it has something to do with the strong params. Any suggestions out there?
Registrations Controller:
class Users::RegistrationsController < Devise::RegistrationsController
# GET /resource/sign_up
def new
@universities = University.all
@programs = Program.all
super
end
# POST /resource
def create
if params["user"]["code"] == ENV["CODE_TO_SIGN_UP"]
User.create(user_params)
else
respond_to do |format|
format.html { return redirect_to new_user_registration_path, notice: 'The code you entered was wrong. Please contact ' + ENV["ADMIN_EMAIL"] }
end
end
super
end
end
protected
def user_params
params.require(:user).permit(:name, :email, :github, :time_zone, :university, :program, :password)
end
end
User Model:
class User < ActiveRecord::Base
belongs_to :university
belongs_to :program
end
University Model:
class University < ActiveRecord::Base
has_many :programs
has_many :users, through: :programs
end
Program Model:
class Program < ActiveRecord::Base
belongs_to :university
has_many :users, through: :university
end
new.html.erb:
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
(...other fields)
<div class="field">
<%= f.label :university_id, 'University' %><br />
<%= f.collection_select(:university_id, University.all, 'id', 'name') %>
</div>
<div class="field">
<%= f.label :program_id, 'Program' %><br>
<%= f.collection_select(:program_id, Program.all, 'id', 'name') %>
</div>
(...other fields)
<% end %>
Github Login User Model:
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:github]
def self.from_omniauth(auth)
where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
user.email = auth.info.email
user.password = Devise.friendly_token[0,20]
user.full_name = auth.info.name # assuming the user model has a name
# If you are using confirmable and the provider(s) you use validate emails,
# uncomment the line below to skip the confirmation emails.
# user.skip_confirmation!
end
end
def self.new_with_session(params, session)
super.tap do |user|
if data = session["devise.github_data"] && session["devise.github_data"]["extra"]["raw_info"]
user.email = data["email"] if user.email.blank?
end
end
end
Application Controller
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: [:github, :github_confirmation, :university_id, :program_id, :full_name, :time_zone])
end
Devise Initializer:
Devise.setup do |config|
config.omniauth :github, "xxx", "xxx",
callback_url: "localhost:3000/users/auth/github/callback"
end
Gemfile:
gem 'devise', '~> 4.2'
gem 'omniauth'
gem 'omniauth-github'
If there's a bit of code I forgot to throw up, please let me know!
In your user_params
method, you're allowing university
and program
but in the form you're passing university_id
and program_id
. Allow these in addition to code
in your user_params
and it should work.
Rails will only permit the whitelisted parameters and disregard any others to prevent mass assignment. That's why university_id
and other unpermitted params are nil in the database.