Search code examples
ruby-on-railsrubysorcery

Displaying specific info to a logged in user


I am creating a customer service web app for our clients that allows them to submit new customer service tickets, once logged in. I have a login system that I created using the sorcery gem, and I have modified it to accept an additional field: client code.

We are assigning client codes to help prevent unauthorized users from creating accounts.

Upon login, it asks for the information like so:

Name:

Email:

Client Code: (we assign this)

Password:

My question is this, is there a way to only display customer service tickets to clients with the same client code? For example, The "Coca-Cola" clients would only see other "Coca-Cola" tickets and the "Pepsi" clients would only see other "Pepsi" tickets, etc.

Here is my Tickets Controller:

class TicketsController < ApplicationController

before_filter :require_login
def new
@ticket = Ticket.new
end

def create
@ticket = Ticket.new(ticket_params)
if
@ticket.save
redirect_to @ticket
flash[:notice] = "Your Ticket has been submitted. We will contact you very soon!"
else
flash[:notice] = "Something went wrong :("
render 'new'
end
end

def show
@ticket = Ticket.find(params[:id])
end

def index
@tickets = Ticket.all
end

def edit
@ticket = Ticket.find(params[:id])
end

def update
  @ticket = Ticket.find(params[:id])

  if @ticket.update(ticket_params)
    redirect_to @ticket
  else
    render 'edit'
  end
end

def destroy
@ticket = Ticket.find(params[:id])
@ticket.destroy
redirect_to tickets_path
end

private
def ticket_params
  params.require(:ticket).permit(:name, :email, :phone, :help)
end
end

Here is the Ticket Index View:

<div class="panel panel-default">
  <div class="panel-heading">Ticket Queue</div>
  <div class="panel-body">
  <table class="table">
   <tr>
    <th>Name</th>
    <th>Phone</th>
    <th></th>
    <th></th>
    </tr>
  <% @tickets.each do |ticket| %>
    <tr>
      <td><%= ticket.name %></td>
      <td><%= ticket.phone %></td>
      <td><%= button_to "View or Edit", ticket_path(ticket), :class => "btn btn-primary     btn-sm", :method => :get %></td>
      <td><%= button_to "Delete", ticket_path(ticket), :class => "btn btn-primary btn-    sm", :method => :delete, data: { confirm: 'Are you sure?' } %></td>   
     </tr>
 <% end %> 
  </table>
</div>

Here is the New Ticket View:

<div class="panel panel-info">
<div class="panel-heading">
<div id="wrapper">
<h1 class="panel-title">New Ticket
<div id="first"><%= button_to "Back", root_path, :class => "btn btn-primary btn-sm",     :method => :get %></div>
</div>
</h1>
</div>
<div class="panel-body">
<%= form_for :ticket, url: tickets_path do |f| %>
  <p>
  <%= f.label "Name:" %>
  <%= f.text_field :name %>
  </p>
   <p>
  <%= f.label "Email:" %>
  <%= f.text_field :email %>
  </p>
  <p>
  <%= f.label :"Phone #:" %>
  <%= f.text_field :phone %>
 </p>
  <p>
  <%= f.label :"How can we help?" %>
  <p><%= f.text_area :help, :cols=> 38, :rows => 8 %></p>
  </p>
   <p>
    <button type="submit" class="btn btn-primary btn-sm"><span class="glyphicon     glyphicon-envelope"></span>   Submit Ticket</button>
  </p>
<% end %>
</div>
</div>

Here is the User Model:

class User < ActiveRecord::Base
authenticates_with_sorcery!

  validates :password, length: { minimum: 3 }
  validates :password, confirmation: true
  validates :password_confirmation, presence: true
  validates :code, inclusion: { in: %w(Client1, Client2), message: "Please enter a     valid Client Code", :allow_nil => false}
  validates :email, uniqueness: true
  validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
end

Here is the New User View:

<%= form_for(@user) do |f| %>
  <% if @user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being     saved:</h2>

      <ul>
      <% @user.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :email %><br>
    <%= f.text_field :email %>
  </div>
  <div class="field">
   <%= f.label :password %><br />
   <%= f.password_field :password %>
</div>
<div class="field">
   <%= f.label :password_confirmation %><br />
   <%= f.password_field :password_confirmation %>
</div>
<div class="field">
   <%= f.label "Client Code" %><br />
   <%= f.text_field :code %>
</div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Here is the User Controller:

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy]
  skip_before_filter :require_login, only: [:index, :new, :create]

  # GET /users
  def index
    @users = User.all
  end

  # GET /users/1
  def show
  end

  # GET /users/new
  def new
    @user = User.new
  end

  # GET /users/1/edit
  def edit
  end

  # POST /users
  def create
    @user = User.new(user_params)
    if @user.save
  redirect_to(:users, notice: 'User was successfully created')
    else
      render :new
    end
  end

  # PATCH/PUT /users/1
  def update
    if @user.update(user_params)
      redirect_to @user, notice: 'User was successfully updated.'
    else
      render :edit
    end
  end

  # DELETE /users/1
  def destroy
    @user.destroy
    redirect_to users_url, notice: 'User was successfully destroyed.'
  end

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

    # Only allow a trusted parameter "white list" through.
    def user_params
      params.require(:user).permit(:email, :password, :password_confirmation, :code)
    end
end

Let me know if you need to see anything else, thank you!


Solution

  • From your example, I would think Users would have an additional database layer:

    class User < ActiveRecord::Base
      belongs_to :company
      has_many :tickets, through: :companies
    end
    
    class Company < ActiveRecord::Base
      has_many :users
      has_many :tickets
    end
    
    class Ticket < ActiveRecord::Base
      belongs_to :company
    end
    

    Then you can easily display tickets associated with each company