Note that there are some explanatory texts on larger screens.

plurals
  1. POCanCan for employees and users
    text
    copied!<p>I have a <code>Ticket</code> model, an <code>Employee</code> model, and a <code>User</code> model.</p> <p>Users and Employees can create tickets, but employees also have tickets assigned to them. So <code>user_id</code> refers to the creator of the ticket, and <code>employee_id</code> refers to the assigned employee (I am not sure if this the best way or not).</p> <p>Ticket.rb</p> <pre><code>class Ticket &lt; ActiveRecord::Base before_save :default_values after_commit :close_solved after_commit :close_canceled before_create :assign_state attr_accessible :description, :title, :employee_department_id, :user_id, :first_name, :last_name , :email, :state_id, :employee_id, :ticket_state, :assign_state belongs_to :employee_department belongs_to :user belongs_to :state belongs_to :employee has_many :replies def default_values self.state_id = 3 if self.state_id.nil? end def to_label ticket_state.to_s end def close_solved if self.ticket_state == "solved" self.update_column(:ticket_state, "closed (solved)") self.save! end end def close_canceled if self.ticket_state == "canceled" self.update_column(:ticket_state, "closed (canceled)") self.save! end end def assign_state if self.employee_id.nil? self.assign_state = "un-assigned" else self.assign_state = "assigned" end end Ticket.all.each do |ticket| if ticket.ticket_state.blank? ticket.ticket_state = 'open' end ticket.save end end </code></pre> <p>Employee.rb</p> <pre><code>class Employee &lt; ActiveRecord::Base # attr_accessible :title, :body after_create :add_to_users attr_accessible :employee_number, :joining_date, :first_name, :middle_name, :last_name, :gender, :job_title, :employee_department_id, :qualification, :experience_detail, :experience_year, :experience_month, :status_description, :date_of_birth, :marital_status, :children_count, :father_name, :mother_name, :husband_name, :blood_group, :nationality_id, :home_address_line1, :home_address_line2, :home_city, :home_state, :home_pin_code, :office_address_line1, :office_address_line2, :office_city, :office_state, :office_pin_code, :office_phone1, :office_phone2, :mobile_phone, :home_phone, :email, :fax, :user_id, :school_id, :employee_category_id, :employee_position_id, :reporting_manager_id, :employee_grade_id, :office_country_id, :home_country_id belongs_to :employee_department belongs_to :employee_category belongs_to :employee_position belongs_to :employee_grade belongs_to :nationality, class_name: 'Country' belongs_to :reporting_manager, class_name: "Employee" belongs_to :school belongs_to :user has_many :tickets def add_to_users new_user = User.new new_user.user_name = self.first_name new_user.first_name = self.first_name new_user.last_name = self.last_name new_user.email = self.email new_user.password = "123456" new_user.password_confirmation = "123456" new_user.user_type_id = 2 new_user.save t = Employee.find(self.id) t.user_id = new_user.id t.save end def to_label full_name = first_name + " " + last_name end def full_name full_name = first_name + " " + last_name end end </code></pre> <p>User.rb</p> <pre><code>class User &lt; ActiveRecord::Base # Include default devise modules. Others available are: # :token_authenticatable, :encryptable, :validatable,:confirmable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :lockable, :timeoutable # Setup accessible (or protected) attributes for your model attr_accessible :email, :user_name, :first_name, :last_name, :password, :password_confirmation, :remember_me, :role_ids, :current_password, :user_type attr_accessor :current_password # attr_accessible :title, :body has_many :assignments has_many :roles, :through =&gt; :assignments has_many :articles has_many :comments has_many :students has_many :guardians has_many :employees has_many :tickets has_many :permissions accepts_nested_attributes_for :tickets def has_role?(role_sym) roles.any? { |r| r.role_name.underscore.to_sym == role_sym } end end </code></pre> <p>Ability.rb</p> <pre><code>class Ability include CanCan::Ability def initialize(user) @user = user || User.new if user.has_role? :administrator can :manage, :all end if user.has_role? :admission_manager can :manage, Student end if user.has_role? :news_manager can :manage, Article end if user.has_role? :ticket_manager can :manage, Ticket end if user.has_role? :student_viewer can :read, Student end if user.has_role? :news_viewer can :read, Article end if user.has_role? :ticket_viewer #he should be able to create tickets and see what he has created. can :create, Ticket can :read, Ticket end end end </code></pre> <p>Ticket_controller.rb</p> <pre><code>class TicketsController &lt; ApplicationController load_and_authorize_resource def index @tickets = Ticket.all @tickets_grid = initialize_grid(Ticket, :include =&gt; [{:user =&gt; :user_type}, :employee_department, :state]) end def show @ticket = Ticket.find(params[:id]) @reply = @ticket.replies.build # this for comments on ticket @state = State.all # this for a model called State which describe the priority of the ticket (Emergency / High / Normal ) end def new @ticket = Ticket.new end def create @ticket = Ticket.new(params[:ticket]) if @ticket.save flash[:notice] = 'Support ticket request created.' redirect_to @ticket else flash[:error] = 'An error occurred please try again!' redirect_to '/dashboard' end end def edit @ticket = Ticket.find(params[:id]) end def update @ticket = Ticket.find(params[:id]) if @ticket.update_attributes(params[:ticket]) flash[:notice] = 'Successfuly updated.' redirect_to tickets_path else flash[:error] = 'An error occurred please try again!' render @ticket end end end </code></pre> <p>I need to allow <code>Employees</code> to be able to manage their assigned tickets, and I need the creator of the ticket to see only the tickets he created.</p> <p>How can I do this using <code>CanCan</code>? I'm open to other suggestions, if it cannot be done with <code>CanCan</code>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload