ARTLoe
ARTLoe

Reputation: 1799

Rails 4 - Couldn't find User without an ID

I'm new to rails, so any explanation & advise would much appreciated.

static_pages_controller.rb

  def recruiterpg
    @user = User.find(params[:user_id])
    @adverts = @user.adverts
    @applications = @user.forms
  end

what am trying to do is: for my views, the recruiterpg.html.erb, i would like any user to be able to view the page not only the current_user to view the page. Could one kindly advise me and explain to me how to define @user correctly in my status_pages_controller.rb. i also tried @user = User.find(params[:id]) but my code still breaks in the views - i get the error message

Couldn't find User without an ID

Upvotes: 3

Views: 6729

Answers (3)

Richard Peck
Richard Peck

Reputation: 76774

Since you're new, here is some information for you:


User Story

Firstly, the best way to resolve errors is to identify your user story.

A "user story" is a software principle in which you put the "user's perspective" first -- explaining how the software should work in conditions defined from how the user engages with it.

One of the main issues you have with your question is your user story is very weak; it's hard to decifer what you're trying to achieve.

Next time you ask a question, you should try your hardest to describe how the user should see your app, before providing code snippets :)


Controller

Your main issue is an antipattern.

An antipattern is basically a "hack" which will likely break another part of your app in future. Kind of like duct tape for software):

#app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController
    def recruiterpg
      @user = User.find(params[:user_id])
      @adverts = @user.adverts
      @applications = @user.forms
    end
end

So you're showing a static page but yet you want to populate it with data?

Hmm...

What you should be doing is something like the following:

#config/routes.rb
resources :users do
   resources :recruiters, only: :index #-> url.com/users/:user_id/recruiters
end

#app/controllers/recruiters_controller.rb
class RecruitersController < ApplicationController
   def index
      @user = User.find params[:user_id]
      @adverts = @user.adverts
      @applications = @user.forms
   end
end

This will allow you to populate the following view:

#app/views/recruiters/index.html.erb
<%= @adverts %>

--

It's important to note the structure of the controller / routes here.

The issue you have is that you're calling a "static page" and expecting to have params available to find a User. This can only happen if you have params available...


Params

Rails is not magic, and as such if you want to look up a user, you have to provide the parameters to do so.

This is why you're able to look up current_user -- the params are already set for this user.

As such, you'll need to use something called nested routes in order to attain a user ID other than that of current_user:

#config/routes.rb
resources :users do
   resources :recruiters #-> url.com/users/:user_id/recruiters
end

Upvotes: 1

Lanny Bose
Lanny Bose

Reputation: 1857

If params[:user_id] isn't defined, you want to find a way to make visible what is being defined.

If you throw the following statements into your controller...

def recruiterpg
  ...
  puts params
  ...
end

...you should see something like the following get spit out in your console when you load the page...

{"controller"=>"static_pages", "action"=>"recruiterpg", "id"=>"49"}

Take a look at the Rails guide for parameters. They can get defined in one of three ways.

One: As a query string similar to Sean's answer above.

Two: Routing parameters. See section 4.3 in the Rails guide. In your case, that would mean you should have something like the following in routes.rb:

get '/dashboard/:user_id' => 'staticpages#recruiterpg'

Note that there's nothing magic about :user_id in that string.

Three: From a form which it doesn't seem like applies here, since a user isn't submitting data.

Upvotes: 2

Sean Huber
Sean Huber

Reputation: 3985

You need to make sure you are passing a user_id to the recruiterpg action. For example, try this url in your browser (set user_id to a known id in the users table):

http://localhost:3000/dashboard?user_id=1

A suggested modification to your action:

def recruiterpg
  @user = User.find params.require(:user_id)
  @adverts = @user.adverts
  @applications = @user.forms
end

Upvotes: 2

Related Questions