0
votes

I'm building an Events app and I'm trying to create a link from the Event show page to the event creator's profile but I'm getting the following error -

ActiveRecord::RecordNotFound in UsersController#show Couldn't find User with 'id'=21

The error highlights this particular line of code in the Users Controller -

def show
    @user = User.find(params[:id])

end

The development log produces this output -

Started GET "/users/21" for ::1 at 2016-04-15 12:37:08 +0100 Processing by UsersController#show as HTML Parameters: {"id"=>"21"} [1m[36mUser Load (0.1ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1[0m [["id", 8]] [1m[35mUser Load (0.2ms)[0m SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 21]] Completed 404 Not Found in 14ms (ActiveRecord: 0.9ms)

ActiveRecord::RecordNotFound (Couldn't find User with 'id'=21): app/controllers/users_controller.rb:14:in `show'

The user id (in this instance 5) is not being passed.I've tried numerous arguments in the show.html.erb page but none will work. Changing the show argument in the users controller to @user = current_user only succeeds in bringing up the profile of the user viewing the event and not the profile of the event creator.

Here's my code -

Events Controller

class EventsController < ApplicationController
before_action :find_event, only: [:show, :edit, :update, :destroy,]
# the before_actions will take care of finding the correct event for us
# this ties in with the private method below
before_action :authenticate_user!, except: [:index, :show]
# this ensures only users who are signed in can alter an event

def index
    if params[:category].blank?
        @events = Event.all.order("created_at DESC")
    else
        @category_id = Category.find_by(name: params[:category]).id
        @events = Event.where(category_id: @category_id).order("created_at DESC")
    end
    # The above code = If there's no category found then all the events are listed
    # If there is then it will show the EVENTS under each category only
end

def show
end

def new
    @event = current_user.events.build
    # this now builds out from a user once devise gem is added
    # after initially having an argument of Event.new
    # this assigns events to users
end
# both update and create actions below use event_params as their argument with    an if/else statement 
def create
    @event = current_user.events.build(event_params)
    # as above this now assigns events to users
    # rather than Event.new

    if @event.save
        redirect_to @event, notice: "Congratulations, you have successfully created a new event."
    else
        render 'new'
    end
end

def edit
    # edit form
    # @edit = Edit.find(params[:id])
    @event = current_user.events.find(params[:id])
end

def update
    if @event.update(event_params)
        redirect_to @event, notice: "Event was successfully updated!"
    else
        render 'edit'
    end
end

def destroy
    @event.destroy
    redirect_to root_path
end

private

def event_params
    params.require(:event).permit(:title, :location, :date, :time, :description, :number_of_spaces, :is_free, :price, :organised_by, :organiser_profile, :url, :image, :category_id)
    # category_id added at the end to ensure this is assigned to each new event created
end

def find_event
    @event = Event.find(params[:id])
end

end

Users Controller -

class UsersController < ApplicationController
before_action :authenticate_user!


def new
    @user = User.new
end


def show
    @user = User.find(params[:id])

end

def create
    @user = User.new(user_params)

        if @user.save
            flash[:success] = "Welcome to Mama Knows Best"
            session[:uid] = @user.id
            redirect_to root_path
        else
            render 'new'
        end
end

def edit  
    @user =  current_user                             
end  

def update
    @user = current_user
        if @user.update(user_params)
            flash[:success] = "Profile successfully updated!"
            redirect_to root_path
        else
            render 'edit'
        end
end


private

def user_params
    params.require(:user).permit(:name, :username, :biography, :email, :url)

end 


end

Show page -

<%= image_tag @event.image.url %>

<h1><%= @event.title %></h1>
<p>Location </p>
<p><%= @event.location %></p>
<p>Date</p>
<p><%= @event.date.strftime('%A, %d %b %Y') %></p>
<p>Time</p>
<p><%= @event.time.strftime('%l:%M %p') %></p>
<!-- above expresses date and time as per UK expectations -->
<p>More details</p>
<p><%= @event.description %></p>
<p>Number of Spaces available</p>
<p><%= @event.number_of_spaces %></p>
<% if @event.is_free? %>
<p>This is a free event</p>
<% else %>
<p>Cost per person</p>
<p><%= @event.price %></p>
<% end %>
<p>Organiser</p>
<p><%= @event.organised_by %></p>
<p>Organiser Profile</p>
<button><%= link_to "Profile", user_path %></button>
<p>Link to Organiser site</p>
<button><%= link_to "Organiser site", @event.url %></button>

<p>Submitted by</p> 
<p><%= @event.user.name %></p>


<% if user_signed_in? and current_user == @event.user %>
<%= link_to "Edit", edit_event_path %>
<%= link_to "Delete", event_path, method: :delete, data: { confirm: "Are you   sure?"} %>
<%= link_to "Back", root_path %>
<% else %>
<%= link_to "Back", root_path %>
<%= link_to "Book the Event", new_event_booking_path(@event) %>
<% end %>

routes -

Rails.application.routes.draw do


  devise_for :users, :controllers => { registrations: 'registrations' }  



  resources :users
  resources :events do

    resources :bookings
  end
  # get 'welcome/index'


  authenticated :user do
    root 'events#index', as: "authenticated_root"
  end


    root 'welcome#index'

  # the above method comes from devise and allows for the site to have a home page
  # for users not signed in and one for when they are signed in


end

I haven't added anything relating to the users profile on the form partial as I didn't believe it to be relevant. Any help would be much appreciated.

3
Is an Event connected to User with any association? - Marek Lipka
<button><%= link_to "Profile", user_path %></button> user_path` is helper which resolves to UserController#show and expects an argument. Do user_path(current_user) - kiddorails
I've tried current_user and it doesn't work. - Mike.Whitehead
Yes, User has_many Events and Events belongs_to User - Mike.Whitehead

3 Answers

2
votes

To reiterate your question, you want a link on the event page that goes to the event organiser's profile page?

<p>Organiser Profile</p>
<button><%= link_to "Profile", user_path(@event.user) %></button>
1
votes

user_path is a path helper in Rails which resolves to RESTful route of /users/:id. This goes in UserController#show and expects params hash to contain :id.

For your case, you are missing the argument. You need to do:

<button><%= link_to "Profile", user_path(current_user) %></button>

It automatically picks up id and passes it to params hash as : {:id => 7} Doc

You may also want fix other such helpers call:

event_path edit_event_path with appropriate argument.

0
votes

What are you using for user authentication, devise or similar gem? Did you build your own? If so do you have current_user defined in the sessions helper? The below code is how current_user could be defined (a la Hartl Rails tutorial). This will allow you to use current_user in views and controllers.

def current_user
    if (user_id = session[:user_id])
      @current_user ||= User.find_by(id: user_id)
    elsif (user_id = cookies.signed[:user_id])
      user = User.find_by(id: user_id)
      if user && user.authenticated?(:remember, cookies[:remember_token])
        log_in user
        @current_user = user
      end
    end
  end

I also noticed in your Users Controller under def create. I believe it should be session[:id] instead of session[:uid]. Please excuse me if this is not the case. Hope this helps.