Devise gem User Authentication

This is my code for my index.html.erb scaffold
as you can see the if else stops a user to "show, edit or destroy" the
entries. However, they can create a new Rota entry by clicking New
Rotum. I can get rid of the admin part in Show, edit, destroy and
everyone will be able to do everything. But I want a user to be able to
only show edit destroy their OWN entry and not everyone elses too
because that is what happens when I authenticate a user to do this?

     <h1>Listing rota</h1>

     <table id = "tabletest">
      <thead>
        <tr>
      <th>Name</th>
      <th>Mobile</th>
      <th>Email</th>
      <th>Category</th>
      <th>Other</th>
      <th colspan="3"></th>
       </tr>
     </thead>

     <tbody>
       <% @rota.each do |rotum| %>
        <tr>
        <td><%= rotum.name %></td>
        <td><%= rotum.mobile %></td>
        <td><%= rotum.email %></td>
        <td><%= rotum.category %></td>
        <td><%= rotum.other %></td>

     <% if current_user.try(:admin?) %>
        <td><%= link_to 'Show', rotum %></td>
        <td><%= link_to 'Edit', edit_rotum_path(rotum) %></td>
        <td><%= link_to 'Destroy', rotum, method: :delete, data: {
confirm: 'Are you sure?' } %></td>
      </tr>
       <% end %>
             <% end %>
     </tbody>
    </table>

    <br>
       <% if user_session %>
    <%= link_to 'New Rotum', new_rotum_path %>
      <% end %>

What does the controller look like?

Try googling for "devise with cancan"

class RotaController < ApplicationController
      before_filter :authenticate_user!, except: ( :Welcome)
  before_action :set_rotum, only: [:show, :edit, :update, :destroy]

  # GET /rota
  # GET /rota.json
  def index
    @rota = Rotum.all
    @is_admin = current_user.try(:admin?)
  end

  # GET /rota/1
  # GET /rota/1.json
  def show
  end

  # GET /rota/new
  def new
    @rotum = Rotum.new
  end

  # GET /rota/1/edit
  def edit
  end

  # POST /rota
  # POST /rota.json
  def create
    @rotum = Rotum.new(rotum_params)

    respond_to do |format|
      if @rotum.save
        format.html { redirect_to @rotum, notice: 'Rotum was
successfully created.' }
        format.json { render :show, status: :created, location: @rotum }
      else
        format.html { render :new }
        format.json { render json: @rotum.errors, status:
:unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /rota/1
  # PATCH/PUT /rota/1.json
  def update
    respond_to do |format|
      if @rotum.update(rotum_params)
        format.html { redirect_to @rotum, notice: 'Rotum was
successfully updated.' }
        format.json { render :show, status: :ok, location: @rotum }
      else
        format.html { render :edit }
        format.json { render json: @rotum.errors, status:
:unprocessable_entity }
      end
    end
  end

  # DELETE /rota/1
  # DELETE /rota/1.json
  def destroy
    @rotum.destroy
    respond_to do |format|
      format.html { redirect_to rota_url, notice: 'Rotum was
successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between
actions.
    def set_rotum
      @rotum = Rotum.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the
white list through.
    def rotum_params
      params.require(:rotum).permit(:name, :mobile, :email, :category,
:other)
    end
end

Jason Fb wrote in post #1159167:

What does the controller look like?

class RotaController < ApplicationController
      before_filter :authenticate_user!, except: ( :Welcome)
  before_action :set_rotum, only: [:show, :edit, :update, :destroy]

  # GET /rota
  # GET /rota.json
  def index
    @rota = Rotum.all
    @is_admin = current_user.try(:admin?)
  end

  # GET /rota/1
  # GET /rota/1.json
  def show
  end

  # GET /rota/new
  def new
    @rotum = Rotum.new
  end

  # GET /rota/1/edit
  def edit
  end

  # POST /rota
  # POST /rota.json
  def create
    @rotum = Rotum.new(rotum_params)

    respond_to do |format|
      if @rotum.save
        format.html { redirect_to @rotum, notice: 'Rotum was
successfully created.' }
        format.json { render :show, status: :created, location: @rotum }
      else
        format.html { render :new }
        format.json { render json: @rotum.errors, status:
:unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /rota/1
  # PATCH/PUT /rota/1.json
  def update
    respond_to do |format|
      if @rotum.update(rotum_params)
        format.html { redirect_to @rotum, notice: 'Rotum was
successfully updated.' }
        format.json { render :show, status: :ok, location: @rotum }
      else
        format.html { render :edit }
        format.json { render json: @rotum.errors, status:
:unprocessable_entity }
      end
    end
  end

  # DELETE /rota/1
  # DELETE /rota/1.json
  def destroy
    @rotum.destroy
    respond_to do |format|
      format.html { redirect_to rota_url, notice: 'Rotum was
successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between
actions.
    def set_rotum
      @rotum = Rotum.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the
white list through.
    def rotum_params
      params.require(:rotum).permit(:name, :mobile, :email, :category,
:other)
    end
end

I will take a look at it, thanks for the advice

The before_action :set_rotum is where you want to put the access control.

Despite what I said earlier, you don't actually need cancan, but as an alternative to this implementation you can use something like cancan for access control.

In your example, you would do something like this (obviously this example assumes you have the rotem object belonging to the user object)

def set_rotem
  @rotem = current_user.rotems.find(params[:id])
  if @rotem.nil?
    render :html => "Not authorized", :status => 401
  end
end

or something like this:

def set_rotem
  @rotem = Rotem.find(params[:id])
  if @rotem.user != current_user
    render :html => "Not authorized", :status => 401
  end
end

-Jason

I am using rails-devise-pundit, It works perfect. However, I tried to
include this code in my controller, but it shows me

undefined method `set_rotum' for #<RotaController:0x000000050413e8>

I'm trying to fix this as we speak, However if you have any suggestions.
Please try and help. Thanks.

Rashid