Home > Net >  Rails pass user object to another controller
Rails pass user object to another controller

Time:07-01

I am building a Rails project where I have a user, and that user has many Tests (it's like a Trivia game). I have a UsersController where I query the user (going to implement login later).

In my view I have a button which "starts" the test. I need to associate the user with a test, because my User has_many Tests (user_id is a foreign key on tests). My question is, how do I pass my @user object to my TestsController so I can associate the created test with the logged in user?

Here is my UsersController:

class UsersController < ApplicationController
  def show
    @user = User.find(1)
  end

  def start_test
    redirect_to tests_path
  end
end

In my users show view I have:

<p>Welcome <%= @user.name %>!</p>

<%= button_to "Start Test", users_start_test_path %>

When the button is clicked I redirect to tests_path which is in TestsController:

class TestsController < ApplicationController        
    def index
      # here I need to create the Test belonging to the user 
    end
end

I am new to Rails and don't know how to pass that @user to TestsController so I can create the test belonging to the user. Theoretically I don't even need the whole @user, just the id. Any help would be greatly appreciated.

CodePudding user response:

The controllers are standalone. They cann't share variables. You could try to send user id intro the request to controller TestsController (or better use an authentication system). Or directly in the TestsController calls User.find(1) again.

CodePudding user response:

The only variable you can pass between controllers is a parameter through the routing (or the session).

So you can have a HTML Form that passes a body to an action inside a different controller OR for what I see in your case by visiting a route and pass a friendly query string parameter, like an ID.

So you could:

<%= button_to "Start Test", users_start_test_path(user_id: @user.id) %>

And then in your TestController:

class TestsController < ApplicationController        
    def index
      @user = User.find params[:user_id]
    end
end

CodePudding user response:

I don't like to pass the current_user variable because it can then be hijacked.

This is how I would set the TestsController

class TestsController < ApplicationController        
    def index
      @tests = current_user.tests
    end
    
    def new
      @test = current_user.tests.new
    end

    def create
      current_user.tests.create(test_params)
    end

    def show
      @test = current_user.tests.find(params[:id]) # this will only find tests scoped to that user
    end

    def edit
      @test = current_user.tests.find(params[:id]) # this will only find tests scoped to that user

    end
    def update
      @test = current_user.tests.find(params[:id]) # this will only find tests scoped to that user
      @test.update(test_params)
    end    

    def test_params
      params.require(:test).permit()
    end

end

This way now you have the test scoped to the user. I am assuming that you have device for user management

  • Related