Tony Tambe
Tony Tambe

Reputation: 573

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.

Upvotes: 2

Views: 170

Answers (1)

MrYoshiji
MrYoshiji

Reputation: 54882

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.

Upvotes: 0

Related Questions