session[:user_id] returns false WHY? RoR - ruby-on-rails

I'm debugging my parks_controller.rb create method because I want to create the park for current user but the current_user method returns nil.
here is the create method:
def create
#park = current_user.parks.new(park_params)
respond_to do |format|
if #park.save
format.html { redirect_to #park, notice: 'Park was successfully created.' }
format.json { render :show, status: :created, location: #park }
else
format.html { render :new }
format.json { render json: #park.errors, status: :unprocessable_entity }
end
end
end
here is the current_user method:
def current_user
if session[:user_id]
#current_user ||= User.find(session[:user_id])
puts "There was no problem"
else
puts "There was a problem"
end
end
It prints out "There was a problem." Here is the user_sessions_controller.rb:
def create
user = User.find_by(email: params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
flash[:success] = I18n.t("thanks_log_in")
redirect_to parks_path
else
flash[:error] = I18n.t("login_problem")
render action: 'new'
end
end
All of my tests are passing except when I try to save the park to the current user, the tests for POST create in parks_controller_spec.rb start to fail and Im done. What am I doing wrong? Where should I look? I already spent at least 10 hours on this and I'm desperate. Please help. Thanks in advance.

Related

Relationship between two models

I having difficulties with the #seller_profile.save statement. Why is it not saving?
def create
#seller_profile = SellerProfile.new(seller_profile_params)
#seller_profile.seller = current_seller
if #seller_profile.save
redirect_to home_index_path
else
puts "Error"
end
end
def current_seller
#current_seller ||= Seller.find(session[:seller_id]) if session[:seller_id]
end
You need to Hanlde your else part with Proper error condition handling
Simple Put will not do the Job
There are following options to handle it
1st by ony Render the JSON
if #seller_profile.save
redirect_to home_index_path
else
render json: #seller_profile.errors.to_json.to_json
end
2nd redirect back with error in notification
if #seller_profile.save
redirect_to home_index_path
else
flash[:error] = #restaurant.errors
redirect_to :back
end
3rd Option to use both Option of Render and Redirect at Same Time
if #seller_profile.save
redirect_to home_index_path
else
respond_to do |format|
format.html { redirect_to :back , flash[:error] = #restaurant.errors }
format.json { render json: #seller_profile.errors.to_json.to_json }
end
end

Rails: Store (merge) parameter after Devise Sign In

I have a form that should be submitted after Sign In but all the viewers can see and fill the form. So, I save the parameters in a session variable. After Sign In, I store the parameters successfully. The problem is that I want to add the user_id (which is foreign key) and store it beside the other parameters (before Sign In, the user_id is unknown).
Part of my Controller's code:
def create
if current_user.nil?
session[:trip] = params
redirect_to new_user_registration_path
else
#trip = Trip.new(trip_params)
respond_to do |format|
if #trip.save
...
private
def set_trip
#trip = Trip.find(params[:id])
end
def trip_params
params.require(:trip).permit(:from, :to, :departure_date, :arrival_date, :user_id)
end
As I mentioned, this code stores the new form parameters successfully. To add (insert or merge) the current_user.id, I tried these different ways separetely:
#trip = Trip.new(trip_params.merge(user_id: => current_user.id)
#trip = Trip.new(trip_params)
#trip.user_id = current_user.id
#trip = current_user.Trip.new(trip_params)
#trip = current_user.trips.new(trip_params)
I've tested all of these ways but still the user_id have not been saved!! Please, help me to understand the problem and its solution for Rails4.
It should work.
def create
if user_signed_in?
#trip = current_user.trips.new(trip_params)
respond_to do |format|
if #trip.save
format.html { redirect_to #trip, notice: 'Trip was successfully created.' }
format.json { render :show, status: :created, location: #trip }
else
format.html { render :new }
format.json { render json: #trip.errors, status: :unprocessable_entity }
end
end
else
session[:trip] = params
redirect_to new_user_session_path
end
end
To solve the problem, I've added this new method to the application_controller.rb:
def after_sign_in_path_for(resource)
# save list if there is a temp_list in the session
if session[:trip].present?
#trip = current_user.trips.new(session[:trip]["trip"])
#trip.save
session[:trip] = nil
return #trip
else
#if there is not temp list in the session proceed as normal
super
end
end
I wish it could be useful for the others.

Users are able to edit other users

I know this was asked before but I double check and made sure that the other questions solutions didn't work for me but anyway, Users are able to edit other users. All you gotta do is change the value id in the address bar and it'll sign you directly into the persons account. I need this fixed and to redirect to their edit page. I've tried multiple things with no luck! I'm not using Devise.
Here is my users_controller.rb,
class UsersController < ApplicationController
before_action :set_user, only: [:edit, :update, :destroy]
before_action :correct_user, only: [:edit, ]
after_action :signed_in_after_register, only: :create
def index
#users = User.all
#user = User.find(session[:user_id])
end
def dashboard
#user = User.find(session[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
#posts = #user.posts.order("created_at DESC").limit(3)
#comment = Comment.new
#post = Post.new
end
def newsfeed
#user = User.find(session[:user_id]) unless session[:user_id] == nil
redirect_to login_path, notice: "You're not logged in" unless #user
#posts = #user.posts.order("created_at DESC").limit(3)
end
def nav
#user = User.find(session[:user_id])
end
def posts
#user = User.find(session[:user_id])
#posts = #user.posts
end
def destroy
#user = User.find(session[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
end
def welcome
#user = User.find(params[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
end
def show
#user = User.find(params[:user_id]) unless session[:user_id] == ""
redirect_to login_path, notice: "You're not logged in" unless #user
#posts = #user.posts.order("created_at DESC").limit(3)
#comment = Comment.new
#post = Post.new
end
def new
#user = User.new
#post = Post.new(params[:post_id])
end
def edit
#user = User.find(params[:user_id]) if params[:user_id]
redirect_to #dashboard_path unless #user
end
def create
#user = User.new(user_params)
respond_to do |format|
if #user.save
format.html { redirect_to dashboard_path, notice: 'User was successfully created!' }
format.json { render :profile, status: :created, location: #user }
else
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to dashboard_path, notice: 'User was successfully updated.' }
format.json { render :profile, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_user
#user = User.find(params[:id])
end
def correct_user
#user = User.find(params[:id]) unless session[:user_id] == ""
end
def signed_in_after_register
session[:user_id] = #user.id
end
def user_params
params.require(:user).permit(:first_name, :last_name, :bio, :password, :password_confirmation, :email, :age, :profile_picture, :post, :body)
end
end
Not to sure what other code you may need to see with this being a controller issue, If you do need any other code of mine just comment and ill edit my question right away! Thank you in advance!
You can prevent users from editing each other's profiles by implementing a current_user helper method and checking it from within your edit and update method.
Add the following method to app/controllers/application_controller.rb
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
This helper will return a User object representing the current user in any view or controller.
Now in your app/controllers/users_controller.rb, replace your update method with the following:
def update
if #user == current_user
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to dashboard_path, notice: 'User was successfully updated.' }
format.json { render :profile, status: :ok, location: #user }
else
format.html { render :edit }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
else
redirect_to some_other_path, notice: 'You do not have permission to edit the profile of another user.'
end
end
You'll also have to set up your users_controller#edit method to use similar logic, but I'll leave that exercise to you, since the point is for you to learn something.

Allow admin to post as user in Rails app

I'm building a rails app where users can log on and see a table of their SAT test scores. Users "has_many" scores and Scores "belongs_to" users. Currently it is set up so that the user can post their own scores. What I want is for an admin to post the scores and the user will just see the table on their show page. The "admin" is just a boolean field in users that I set to true for the admins.
Here is the scores controller:
class ScoresController < ApplicationController
def index
#scores = Score.all
end
def show
#score = Score.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #score }
format.js
end
end
def new
#score = Score.new
end
def create
#score = current_user.scores.new(params[:score])
#user = current_user
respond_to do |format|
if #score.save
format.html { redirect_to #score.user, notice: 'Score was successfully created.' }
format.json { render json: #score, status: :created, location: #score }
else
format.html { render action: 'new' }
format.json { render json: #score.errors, status: :unprocessable_entity }
end
end
end
def update
#score = Score.find(params[:id])
respond_to do |format|
if #score.update(params[:score])
format.html { redirect_to #score.user, notice: 'Score was successfully updated.' }
format.json { render action: 'show', status: :ok, location: #score }
else
format.html { render action: 'edit' }
format.json { render json: #score.errors, status: :unprocessable_entity }
end
end
end
def edit
#score = Score.find(params[:id])
end
def destroy
#score = Score.find(params[:id])
if #score.present?
#score.destroy
end
redirect_to #score.user
end
end
I know I'd have to change the scores controller so that it didn't rely on current_user to create and edit scores. I'm just not sure how to implement that. Let me know if you need more info! Thanks.
First, you'll need to add a select tag in your view to select which user you want to post as:
- if current_user.is_admin?
= f.select :user_id, options_for_select(User.all.map{ |u| [u.username, u.id] })
- else
= f.hidden_field :user_id, value: current_user.id
Then, on the server-side, we will double-check that current_user is an admin to allow the creation of a Score for another User:
def create
#score = Score.new(params[:score])
if current_user.id != #score.user_id # Someone is trying to create a Score for someone else!
#score.errors.add(:user_id, "You shall not create Score for other users than you, you evil hacker!") unless current_user.is_admin?
end
respond_to do |format|
if #score.save
format.html { redirect_to #score.user, notice: 'Score was successfully created.' }
format.json { render json: #score, status: :created, location: #score }
else
format.html { render action: 'new' }
format.json { render json: #score.errors, status: :unprocessable_entity }
end
end
end
I omitted the part #user = current_user because usually current_user is a helper method than can be accessed directly in the views, so instead of using #user in the create view, use current_user instead.

undefined method `password' for nil:NilClass

I get this error when I try to get to the users#login page.
my controller is
class UsersController < ApplicationController
# GET /users
# GET /users.json
def login
#username = User.find_by_username(params[:username])
#password = params[:password]
if(#username.password == #password)
format.json { render json: #username, notice: "Login Successful!!" }
end
end
def index
#users = User.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #user }
end
end
# GET /users/1
# GET /users/1.json
def show
#user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #user }
end
end
# GET /users/new
# GET /users/new.json
def new
#user = User.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #user }
end
end
# GET /users/1/edit
def edit
#user = User.find(params[:id])
end
# POST /users
# POST /users.json
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PUT /users/1
# PUT /users/1.json
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# DELETE /users/1
# DELETE /users/1.json
def destroy
#user = User.find(params[:id])
#user.destroy
respond_to do |format|
format.html { redirect_to users_url }
format.json { head :no_content }
end
end
end
I researched and the problems people had was that either they didnt migrate the column "password" or there password was actually "Password" but when i get into rails console and run
user = User.new
=> #<User id: nil, name: nil, email: nil, username: nil, created_at: nil, updated_at: nil, password: nil>
so I guess that is not my problem.
It seems that you are not getting the record of user from database. There is two possibilities
1) Either the user is not in database or
2) The parameter is wrong i.e. params[:username]
You need to check that parameter is coming as expected and if its correct then try to look at the database that record is available.
You can check params like this:
puts params[:username]
puts params[:password]
Or you can also check from server console.
Hope this helps!!!
The problem is that #username is nil. #username is a confusing name anyway, it should be #user.

Resources