Im trying to register users on my rails site. When I click the register button on the register page this is what shows up:
ActiveModel::ForbiddenAttributesError in UserController#register
ActiveModel::ForbiddenAttributesError
Here is the code for my user_controller.rb file:
class UserController < ApplicationController
def index
#title = "RailsSpace User Hub"
end
def register
#title = "Register"
if request.post? and params[:user]
#user = User.new(params[:user])
end
if #user.save
flash[:notice] = "User #{#user.screen_name} created!"
redirect_to :action => "index"
end
end
end
It's complaining about line 11: #user = User.new(params[:user]) Im following code from a book so I dont know what's wrong with it.
Does anyone have any suggestions? Thanks for all your help in advance.
You should use strong parameters.
The UserController should look like this:
class UserController < ApplicationController
def index
#title = "RailsSpace User Hub"
end
def register
#title = "Register"
if request.post? and params[:user]
#user = User.new(user_params)
end
if #user.save
flash[:notice] = "User #{#user.screen_name} created!"
redirect_to :action => "index"
end
end
private
def user_params
# Add the user attributes that you sent with post (form) to the permit method.
params.require(:user).permit(:name, :screen_name)
end
end
Related
I have some code here that is supposed to create a session upon login, and create "#current_user". However, neither of these things are working, and after 2 days of speculating, I can't figure out why.
Users controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to login_path
flash[:success] = "Account created. You may now log in"
else
redirect_to '/signup'
flash[:warning] = "Something went wrong. Try again."
end
end
private
def user_params
params.require(:user).permit(:username, :jabber_id, :password)
end
end
Sessions controller:
class SessionsController < ApplicationController
def new
end
def create
#user = User.find_by_username(params[:session][:name])
if #user && #user.authenticate(params[:session][:password])
session[:user_id] = #user.id
redirect_to '/posts'
else
session[:user_id] = nil
flash[:warning] = "Failed login- try again"
redirect_to '/login'
end
end
def destroy
session[:session_id] = nil
redirect_to login_path
end
end
Application controller:
class ApplicationController < ActionController::Base
def current_user
return unless session[:user_id]
#current_user ||= User.find(session[:user_id])
end
def require_user
redirect_to '/login' unless current_user
end
end
I have created an app with simple login authentication, it is actually a twitter clone. The user logs in and access the pages, etc.
But when the user posts something from there profile. It gives an error
NoMethodError in RibbitsController#create
undefined method `id=' for nil:NilClass
The error is around line 5:
class RibbitsController < ApplicationController
def create
#ribbit = Ribbit.create(user_ribbits)
#ribbit.userid = current_user.id
if #ribbit.save
redirect_to current_user
else
flash[:error] = "Problem!"
redirect_to current_user
end
end
private
def user_ribbits
params.require(:ribbit).permit(:content, :userid)
end
end
The request given to app:
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"dwVmjDNO4GOowphGFgChMDBxBfvka+M/xSUHvJMECzwxtv4NF6OuWtiaX74NLz91OwQJ9T9+wm7yMiPQ0BLpGA==",
"ribbit"=>{"content"=>"hi. test.\r\n"},
"commit"=>"Ribbit!"}
The sessions controller:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_username(params[:username])
if user && user.authenticate(params[:password])
session[:userid] = user.id
redirect_to rooturl, notice: "Logged in!"
else
flash[:error] = "Wrong Username or Password."
redirect_to root_url
end
end
def destroy
session[:userid] = nil
redirect_to root_url, notice: "Logged out."
end
end
The users controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.create(user_params)
if #user.save
session[:user_id] = #user.id
redirect_to #user, notice: "Thank you for signing up!"
else
render 'new'
end
end
def show
#user = User.find(params[:id])
#ribbit = Ribbit.new
end
private
def user_params
params.require(:user).permit(:name, :username, :email, :password, :password_confirmation, :avatar_url)
end
end
And the application controller
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
end
I would really appreciate it if you guys would help!
Thanks.
You're trying to assign current_user.idto #ribbit.userid without ensuring that current_user is set. 'current_user' would be set only if a user has been previously saved before.
Therefore, you need either to make sure that an authenticated user is trying to create a Ribbit, or if you consider the userid as a non mandatory field, you can simply change your line 5 by:
#ribbit.userid = current_user.id unless current_user.blank?
If you only want authenticated user to create Ribbits, then consider using a gem to handle authentication such as Devise. You could then use before_filter :authenticate_user! in your controller to make sure users are properly authenticated.
The error is coming in the create method user mailer section.
I am trying to resolve it, but nothing happens.
How can it be resolved? I come when I apply the validations.
The error is: Expected a URI like gid://app/Person/1234: #<URI::GID gid://email>
My mailer controller:
class UserMailer < ApplicationMailer
def welcome_email(user)
#user = user
#url = 'http:3000//example.com/login#u'
mail(to: #user.email, subject: 'Welcome to My Awesome Site')
end
end
My user controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new(user_params)
#user.save
UserMailer.welcome_email(#user).deliver_later[here the error come about the invalid url]
render 'token'
end
def verify
#user = User.authenticate(params[:auth_token])
if #user
redirect_to edit_user_path(#user)
else
flash.now.alert = "Invalid email or password"
render 'token', :alert =>"Invalid email or password"
end
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
if #user.update(user_params)
redirect_to new_login_path
else
render 'edit'
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :dob, :email,
:password, :confirm_password, :auth_token)
end
end
You are trying to pass the Mailer an unpersisted object, ie. an object that was not saved to the database.
From your code, that means that the previous #user.save statement failed probably due to a validation error. In that case, you don't want to send the email anyway.
Change your create action like this:
def create
#user = User.new(user_params)
if #user.save
UserMailer.welcome_email(#user).deliver_later
render 'token'
else
flash[:error] = 'User was not saved'
render 'new'
end
end
I can't figure out why the #user variable is not being found. It's throwing the error inside of a view where I try to link to the user, and it mentions the index of Users.
What am I doing wrong?
More info: They login via a session page, and then I redirect them to the "User view" to then use the application as a logged in user. The session is created successfully.
Routes.rb
resources :users
resources :sessions
Users Controller
class UsersController < ApplicationController
def new
#user = User.new
end
def create
#user = User.create!(user_params)
redirect_to users_path, notice: "Successfully created #{#user.name}"
end
def index
#user = User.find_by_email(params[:email])
end
private
def user_params
params.require(:user).permit!
end
end
Sessions Controller
class SessionsController < ApplicationController
def new
end
def create
#user = User.find_by_email(params[:email])
if #user && #user.authenticate(params[:password])
session[:user_id] = #user.id
redirect_to users_path, notice: "Logged in as #{#user.name}"
else
flash.now.alert = "Email or password is invalid"
render "new"
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "Logged out!"
end
end
User View
<%= link_to user.name, edit_user_path(user) %>
The user variable in your view is being seen as a local variable, which is undefined. Use #user instance variable instead of user as it's #user that's defined in your index action.
<%= link_to #user.name, edit_user_path(#user) %>
Update:
So basically the problem was in the OP's user's migration, the option id: false was set. Which led to creation of users table without the id column and #user.id was always nil. Removing this option from the migration fixed the issue!
I am trying to block all default methods except create and update in my users controller using declerative_authorization. But at the time I add filter_resource_access or filter_access_to into my usersController i always get "Couldn't find User without an ID". Anyone care to explain why this could be happening?
class UsersController < ApplicationController
filter_resource_access
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
flash[:notice] = "Account registered!"
redirect_to account_url
else
render :action => :new
end
end
def show
#user = #current_user
end
def edit
#user = #current_user
end
def update
#user = #current_user # makes our views "cleaner" and more consistent
if #user.update_attributes(params[:user])
flash[:notice] = "Account updated!"
redirect_to account_url
else
render :action => :edit
end
end
end
You should set the #user variable before the filter_access_to call with a before_filter as declarative_authorization tries to access #user when you call filter_access_to.
before_filter :set_user
filter_access_to :all
...
protected
def set_user
#user = #current_user
end
Maybe you are setting the attribute_check parameter to true in your filter_access_to call? I have a similar controller and I don't really need the before_filter.
Another thing that might be causing it is a using_access_control call in your User model.