User has_many reviews association - ruby-on-rails

I'm trying to create a way for users to review other users.
When I try going on www.site.com/users/1/reviews/new , i get redirected to my homepage with 'resource not found'. I'm guessing it has to do with my routes?
routes.rb
Rails.application.routes.draw do
devise_for :users,
:controllers => { registrations: 'registrations',
omniauth_callbacks: 'omniauth_callbacks'} #<-- that thing is for STRIPE!
#STRIPE
resources :charges
#MAILBOXER
resources :conversations, only: [:index, :show, :destroy] do
member do
post :reply
post :restore
post :mark_as_read
end
collection do
delete :empty_trash
end
end
resources :messages, only: [:new, :create]
#user reviews (THE PROBLEM)
resources :users do
resources :reviews
end
#categories associatoin
resources :categories, except: [:destroy]
root 'home#index'
get 'profile', to: 'users#show'
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable
#Categories association stuff
has_many :user_categories
has_many :categories, through: :user_categories
#user review association stuff
has_many :reviews
acts_as_messageable
def mailboxer_email(object)
email
end
end
review.rb
class Review < ActiveRecord::Base
belongs_to :user
end
reviews_controller.rb
class ReviewsController < ApplicationController
before_action :set_review, only: [:show, :edit, :update, :destroy]
before_action :set_user
before_action :authenticate_user!
# GET /reviews
# GET /reviews.json
def index
#reviews = Review.all
end
# GET /reviews/1
# GET /reviews/1.json
def show
end
# GET /reviews/new
def new
#review = Review.new
end
# GET /reviews/1/edit
def edit
end
# POST /reviews
# POST /reviews.json
def create
#review = Review.new(review_params)
#review.user_id = current_user.id
#review.user_id = #user.id
end
# PATCH/PUT /reviews/1
# PATCH/PUT /reviews/1.json
def update
respond_to do |format|
if #review.update(review_params)
format.html { redirect_to #review, notice: 'Review was successfully updated.' }
format.json { render :show, status: :ok, location: #review }
else
format.html { render :edit }
format.json { render json: #review.errors, status: :unprocessable_entity }
end
end
end
# DELETE /reviews/1
# DELETE /reviews/1.json
def destroy
#review.destroy
respond_to do |format|
format.html { redirect_to reviews_url, notice: 'Review was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_review
#review = Review.find(params[:id])
end
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def review_params
params.require(:review).permit(:rating, :comment)
end
end

def set_user
#user = User.find(params[:id])
end
should be:
def set_user
#user = User.find(params[:user_id])
end

Related

1 error prohibited this channel from being saved:

i have a rails app with users and posts, i have added another sacffold called channels, now the relationship goes like the user can create both post and channels and the channels belongs to users, post belongs to both users and channels, to add user id to channels i have created a migration, everything looks good but i am getting this error while creating a channel.
(Here is a screenshot of the exact error)
This is what am getting on the command line:
Started POST "/channels" for 127.0.0.1 at 2017-12-16 13:30:32 +0530
Processing by ChannelsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"IJvvEe+TR6buacH5UwtiLSJglMkq7a+Q4x7VOTqALcGka4j6tG7lPi/7kYnCQ/nzmO7PNe2eSan3sBz9NqKV2g==", "channel"=>{"name"=>"dhfkdhfk", "description"=>"jdfjdfh", "tagline"=>"jdfjdfhj", "category"=>"jdfjdf", "avatar"=>""}, "commit"=>"Create Channel"}
User Load (2.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
(2.6ms) BEGIN
(1.8ms) ROLLBACK
Rendered channels/_form.html.erb (11.5ms)
Rendered channels/new.html.erb within layouts/application (13.3ms)
Rendered layouts/_avatar_dropdown.html.erb (7.4ms)
Rendered layouts/_header.html.erb (12.6ms)
Rendered layouts/_alert_messages.html.erb (0.5ms)
Completed 200 OK in 367ms (Views: 345.3ms | ActiveRecord: 6.7ms)
Add_user_id_to_channel.rb
class AddUserIdToChannels < ActiveRecord::Migration
def change
add_reference :channels, :user, index: true, foreign_key: true
end
end
channel.rb
class Channel < ActiveRecord::Base
validates :name, :description, :user_id, presence: true
belongs_to :user
has_many :posts, dependent: :destroy
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:omniauthable, :omniauth_providers => [:facebook, :twitter, :google_oauth2]
act_as_mentionee
validates :username, presence: true
validate :avatar_image_size
has_many :posts, dependent: :destroy
has_many :channels, dependent: :destroy
has_many :responses, dependent: :destroy
has_many :likes, dependent: :destroy
after_destroy :clear_notifications
after_commit :send_welcome_email, on: [:create]
mount_uploader :avatar, AvatarUploader
include UserFollowing
include TagFollowing
include SearchableUser
include OmniauthableUser
private
# Validates the size on an uploaded image.
def avatar_image_size
if avatar.size > 5.megabytes
errors.add(:avatar, "should be less than 5MB")
end
end
# Returns a string of the objects class name downcased.
def downcased_class_name(obj)
obj.class.to_s.downcase
end
# Clears notifications where deleted user is the actor.
def clear_notifications
Notification.where(actor_id: self.id).destroy_all
end
def send_welcome_email
WelcomeEmailJob.perform_later(self.id)
end
end
user_controller
class UsersController < ApplicationController
before_action :authenticate_user!, only: [:edit, :update]
before_action :authorize_user, only: [:edit, :update]
before_action :set_user, only: [:show, :edit, :update]
def show
#followers_count = #user.followers.count
#following_count = #user.following.count
#latest_posts = #user.posts.latest(3).published
#recommended_posts = #user.liked_posts.latest(4).published.includes(:user)
end
def update
if #user.update(user_params)
redirect_to #user
else
render :edit, alert: "Could not update, Please try again"
end
end
private
def set_user
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:description, :avatar, :location, :username)
end
def authorize_user
unless current_user.slug == params[:id]
redirect_to root_url
end
end
end
channel_controller
class ChannelsController < ApplicationController
before_action :set_channel, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:show]
before_action :authorize_user, only: [:edit, :update, :destroy]
# GET /channels
# GET /channels.json
def index
#channels = Channel.all
end
# GET /channels/1
# GET /channels/1.json
def show
end
# GET /channels/new
def new
#channel = Channel.new
#channel = current_user.channels.build
#user = current_user
end
# GET /channels/1/edit
def edit
end
# POST /channels
# POST /channels.json
def create
#channel = current_user.channels.build(channel_params)
#channel = Channel.new(channel_params)
#user = current_user
respond_to do |format|
if #channel.save
format.html { redirect_to #channel, notice: 'Channel was successfully created.' }
format.json { render :show, status: :created, location: #channel }
else
format.html { render :new }
format.json { render json: #channel.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /channels/1
# PATCH/PUT /channels/1.json
def update
respond_to do |format|
if #channel.update(channel_params)
format.html { redirect_to #channel, notice: 'Channel was successfully updated.' }
format.json { render :show, status: :ok, location: #channel }
else
format.html { render :edit }
format.json { render json: #channel.errors, status: :unprocessable_entity }
end
end
end
# DELETE /channels/1
# DELETE /channels/1.json
def destroy
#channel.destroy
respond_to do |format|
format.html { redirect_to channels_url, notice: 'Channel was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_channel
#channel = Channel.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def channel_params
params.require(:channel).permit(:name, :description, :tagline, :category, :avatar, :user_id)
end
def authorize_user
begin
#channel = current_user.channels.find(params[:id])
rescue
redirect_to root_url
end
end
end
In model of channel you made it 'user_id' compulsory filed by adding presence: true
validates :name, :description, :user_id, presence: true
so you have to pass user_id in your parameters. you can do that by adding hidden_filed in your view as
<%= f.hidden_field :user_id, value: #user %>
or if you don't required 'user_id' remove form validates like these:
validates :name, :description, presence: true
Change
#channel = current_user.channels.build(channel_params)
#channel = Channel.new(channel_params)
To
#channel = current_user.channels.build(channel_params)

error while adding tags to a post in rails

I wanted to add tags to my products in rails project, so i watched a youtube video how to do it (https://www.youtube.com/watch?v=rzx5MrCa0Pc&t=254s)
I did all he did, but i when i add a new product i get an error -
'New Product
1 error prohibited this product from being saved:
User must exist' , right above my new product form
how do i fix it.
MY ROUTES
Rails.application.routes.draw do
devise_for :users, :controllers => { :registrations => "registrations"}
resources :products
get 'home/ContactUs'
get 'home/Login'
get 'home/Store'
get 'home/blogs'
get 'home/index'
resources :home
root 'home#index'
MY PRODUCT MODEL
class Product < ActiveRecord::Base
belongs_to :user
has_many :taggings, dependent: :destroy
has_many :tags, through: :taggings
def self.tagged_with(name)
Tag.find_by!(name: name).products
end
def all_tags=(names)
# names="music, spotify"
self.tags = names.split(',').map do |name|
Tag.where(name: name).first_or_create!
end
end
def all_tags
tags.map(&:name).join(", ")
end
end
TAG MODEL
class Tag < ApplicationRecord
has_many :taggings, dependent: :destroy
has_many :products, through: :taggings
end
TAGGINGS MODEL
class Tagging < ActiveRecord::Base
belongs_to :product
belongs_to :tag
end
USER MODEL
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :products
end
PRODUCT_CONTROLLER
class ProductsController < ApplicationController
# before_action :authenticate_user!
before_action :set_product, only: [:show, :edit, :update, :destroy]
# GET /products
# GET /products.json
def index
if params[:tag]
#products = Product.tagged_with(params[:tag])
else
#products = Product.all
end
end
# GET /products/1
# GET /products/1.json
def show
end
# GET /products/new
def new
#product = Product.new
end
# GET /products/1/edit
def edit
end
# POST /products
# POST /products.json
def create
#product = Product.new(product_params)
respond_to do |format|
if #product.save
format.html { redirect_to #product, notice: 'Product was successfully created.' }
format.json { render :show, status: :created, location: #product }
else
format.html { render :new }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /products/1
# PATCH/PUT /products/1.json
def update
respond_to do |format|
if #product.update(product_params)
format.html { redirect_to #product, notice: 'Product was successfully updated.' }
format.json { render :show, status: :ok, location: #product }
else
format.html { render :edit }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
# DELETE /products/1
# DELETE /products/1.json
def destroy
#product.destroy
respond_to do |format|
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_product
#product = Product.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def product_params
params.require(:product).permit(:filetype, :title, :img_url, :description, :all_tags, :price, :uploaded_by, :tutorial_url)
end
end
User must exist
The problem is Product belongs to User but you are trying to create the product without passing user_id which will create an orphan product
Solution: Change
def create
#product = Product.new(product_params)
to
def create
#product = current_user.products.new(product_params)
Also, You will need to change set_product method to make sure you can update or delete only products created by user
def set_product
#product = current_user.products.find(params[:id])
end

Cannot access "Current user" in rails

I am using devise and devise_ldap for my rails authentication. I am trying to use the built in helper, current user to display the users email on the welcome page of my application.
This is the code that I have tried to use to:
<% if user_signed_in? %>
<div>Signed in as... <%= current_user.email %></div>
<% end %>
when I sign in to the application, I get the error;
undefined method `email' for nil:NilClass
Here is my routes.rb
Rails.application.routes.draw do
devise_for :users
resources :users
resources :systems do
member do
get :targets, :sources
end
root 'systems#index'
end
and my users controller:
class UsersController < ApplicationController
authorize_resource
before_action :set_user, only: [:show, :edit, :update, :destroy]
# GET /users
def index
#users = User.all.order("display_name asc")
end
# GET /users/1
def show
end
# GET /users/new
def new
#user = User.new
end
# GET /stories/1/edit
def edit
respond_to do |format|
format.html
format.js
end
end
# POST /stories
def create
#user = User.new(user_params)
respond_to do |format|
puts 'user controller'
if #user.save!
format.html { redirect_to user_path(#user), notice: 'User was successfully created.' }
else
format.html { render :new }
end
end
end
# PATCH/PUT /stories/1
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to user_path(#user), notice: 'User was successfully updated.' }
else
format.html { render :edit }
end
end
end
# DELETE /stories/1
def destroy
#user.destroy
respond_to do |format|
format.html { redirect_to users_path notice: 'User was successfully destroyed.' }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user
#user = User.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def user_params
params.require(:user).permit(:display_name, :email, :username)
end
end
my users model:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
before_create :rememberable_value
before_save :get_ldap_values
devise :ldap_authenticatable, :rememberable, :trackable, :validatable
def get_ldap_values
if self.username
self.email = Devise::LDAP::Adapter.get_ldap_param(self.username,"mail").first if Devise::LDAP::Adapter.get_ldap_param(self.username,"mail")
self.display_name = Devise::LDAP::Adapter.get_ldap_param(self.username,"displayName").first if Devise::LDAP::Adapter.get_ldap_param(self.username,"displayName")
end
end
# def role?(role)
# return !!self.roles.find_by_name(role.to_s.camelize)
# end
def email_required?
false
end
def email_changed?
false
end
def rememberable_value
self.remember_token ||= Devise.friendly_token
end
def name_to_display
if self.display_name
self.display_name
else
self.username
end
end
def password_required?
false
end
def password_match?
self.errors[:password] << "can't be blank" if password.blank?
self.errors[:password_confirmation] << "can't be blank" if password_confirmation.blank?
self.errors[:password_confirmation] << "does not match password" if password != password_confirmation
password == password_confirmation && !password.blank?
end
end
I am not sure what I am missing to be able to access the current users information after a successful sign in.
Update
Here is the new routes file:
Rails.application.routes.draw do
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
get "/users/sign_in" => "devise/sessions#new"
# delete "/logout" => "devise/sessions#destroy"
end
devise_for :users
authenticate(:user) do
resources :users
resources :reports
resources :change_logs, only: [:index, :show]
resources :systems do
member do
get :targets, :sources
end
resources :change_logs, module: :systems
resources :components do
resources :change_logs, module: :components
end
resources :c_relations
end
resources :integrations
get '/static_pages/home' # => 'static_pages#home', as: 'home'
root 'systems#index'
end
In routes.rb you should enclose the rows following
devise_for :users
in a block
authenticate(:user) do
resources :users
[...]
end
The problem was that I had overridden the devise mapping and current_user. I removed them and was able to access current user in my views.
Do you have before_action :authenticate_user! in your controller chain at all?
Current_user could be nil after signin is if you aren't asking devise to authenticate the action.

What am I missing to get a profile page to include additional fields such as address, avatar, phone number

I am using Ruby on Rails and utilized devise for my log in and registration. After signing up, I get this error message:
NoMethodError in Devise::SessionsController#create undefined method profile_path' for #<Devise::SessionsController:0x007f9425b1f9c0>
I used rails generate scaffold profile and have the following code:
profiles_controller.rb
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
def profile
end
# GET /profiles
# GET /profiles.json
def index
#profiles = Profile.all
end
# GET /profiles/1
# GET /profiles/1.json
def show
end
# GET /profiles/new
def new
#profile = Profile.new
end
# GET /profiles/1/edit
def edit
#profile = Profile.find_by user_id: current_user.id
#attributes = Profile.attribute_names - %w(id user_id created_at updated_at)
end
# POST /profiles
# POST /profiles.json
def create
#profile = Profile.new(profile_params)
respond_to do |format|
if #profile.save
format.html { redirect_to #profile, notice: 'Profile was successfully created.' }
format.json { render :show, status: :created, location: #profile }
else
format.html { render :new }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /profiles/1
# PATCH/PUT /profiles/1.json
def update
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to #profile, notice: 'Profile was successfully updated.' }
format.json { render :show, status: :ok, location: #profile }
else
format.html { render :edit }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
#profile.destroy
respond_to do |format|
format.html { redirect_to profiles_url, notice: 'Profile was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_profile
#profile = Profile.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def profile_params
params[:profile]
end
end
application_controller.rb
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) << :name
devise_parameter_sanitizer.for(:account_update) << :name
end
def after_sign_in_path_for(resource)
profile_path(resource)
end
def after_sign_up_path_for(resource)
profile_path(resource)
end
end
profile.rb
class Profile < ActiveRecord::Base
belongs_to :user
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :pins, dependent: :destroy
validates :name, presence: true
has_one :profile
before_create :build_profile #creates profile at user registration
end
routes.rb
Rails.application.routes.draw do
resources :profiles, only: [:edit]
resources :pins
devise_for :users
#devise_for :installs
root "pins#index"
get "about" => "pages#about"
Thanks.
You need to use the plural: profiles_path rather than profile_path, in application_controller.rb.

Connecting a User(devise) to their Profile

I am using Devise and am trying to allow each User to create 1 Profile. I am able to send the the newly registered User to the page where they can create a Profile, but once the User logs out and back in it will not go to the Profile Show page.
In other words-
I can sign up a new User and send the User to the Create Profile page, then I can create a Profile with the new User(I am not sure the Profile is saving correctly)... After I log out and sign in I recieved the error:
ActiveRecord::RecordNotFound in ProfilesController#show
Couldn't find Profile without an ID
I would like the User to be sent to their Profile Show page...
Any thoughts on the issue?
The code (sorted by files) is below…
user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me
has_one :profile
end
profile.rb
class Profile < ActiveRecord::Base
attr_accessible :first_name, :last_name
belongs_to :user
end
profiles_controller.rb
class ProfilesController < ApplicationController
# GET /profiles
# GET /profiles.json
def index
#profiles = Profile.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #profiles }
end
end
# GET /profiles/1
# GET /profiles/1.json
def show
#profile = Profile.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #profile }
end
end
# GET /profiles/new
# GET /profiles/new.json
def new
#profile = Profile.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #profile }
end
end
# GET /profiles/1/edit
def edit
#profile = Profile.find(params[:id])
end
# POST /profiles
# POST /profiles.json
def create
#profile = Profile.new(params[:profile])
respond_to do |format|
if #profile.save
format.html { redirect_to #profile, notice: 'Profile was successfully created.' }
format.json { render json: #profile, status: :created, location: #profile }
else
format.html { render action: "new" }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# PUT /profiles/1
# PUT /profiles/1.json
def update
#profile = Profile.find(params[:id])
respond_to do |format|
if #profile.update_attributes(params[:profile])
format.html { redirect_to #profile, notice: 'Profile was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
#profile = Profile.find(params[:id])
#profile.destroy
respond_to do |format|
format.html { redirect_to profiles_url }
format.json { head :no_content }
end
end
end
registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
request.env['omniauth.origin'] || stored_location_for(resource) || new_profile_path
end
end
application_controller.rb
class ApplicationController < ActionController::Base
def after_sign_in_path_for(resource)
request.env['omniauth.origin'] || stored_location_for(resource) || show_path(resource.profile)
end
end
routes.rb
BaseApp::Application.routes.draw do
resources :profiles
get "users/show"
devise_for :users, :controllers => { :registrations => "registrations" }
resources :users
match '/show', to: 'profiles#show'
match '/signup', to: 'users#new'
root to: 'static_pages#home'
match '/', to: 'static_pages#home'
…
end
In your controller you use the following code #profile = Profile.find(params[:id]). When signing in params[:id] must be nil.
It's not nil when you redirect after creating because you send in an id here redirect_to #profile. That translates to redirect_to profile_path(#profile). When you use the /match path there is no id.
So one solution would be to use the helper current_user in the ProfileController's show action. Replace #profile = Profile.find(params[:id]) with #profile = current_user.profile. That might change your desired functionality as it will require a user to be signed in. This will keep the math path (/show url). It works because it no long relies on an id.
You could alternatively change the show_path(resource.profile) to profile_path(resource.profile). That will use the resources profiles path with the url /profiles/:id instead of show/ you were possibly looking for.
With answer #Phil provide I solved another problem in my project. Thanks \o/
ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-linux]
Rails 4.0.0
And your case, I solved this way:
Add inverse_of: in user and profile model:
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_one :profile, inverse_of: :user
end
profile.rb
class Profile < ActiveRecord::Base
belongs_to :user, inverse_of: :profile
validates :first_name, :user_id, :presence => true
validates :gender, :inclusion => {:in => %w(M F)}
end
In your application_controller.rb
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
# redirect user after login
def after_sign_in_path_for(resource)
unless current_user.profile.nil?
profiles_path
else
flash[:alert] = "Please complete your profile"
new_profile_path
end
end
# redirect after logout
def after_sign_out_path_for(resource_or_scope)
new_user_session_path
end
end
This works for me, I hope this helps

Resources