Ownership.md
February 3, 2015 ยท View on GitHub
Few words about Ownership
owner?(object) - default method for ownership checking
In fact, checking for ownership is not a task of TheRole, because relations between objects in Rails App sometimes can be confusing.
It's impossible to create universal method for ownership checking. But TheRole provide owner?(object) method for simple ownership checking. How does it works?
@user.owner?(object) just compare @user.id with object.user_id, if they are equal method will return true
It means, that object have to provide user_id field or method.
If you want to use default ownership method from TheRole, usually, you have to add user_id field into migration file.
This is a case, when @user.owner?(@page) will works correctly:
class CreatePages < ActiveRecord::Migration
def change
create_table :pages do |t|
# Field for ownership checking
t.integer :user_id
t.string :title
t.text :content
end
end
end
class User < ActiveRecord::Base
include TheRole::Api::User
has_many :pages
end
class Page < ActiveRecord::Base
belongs_to :user
end
Now you can check something, for instance:
@user.owner?(@page) #=> true | false
or
@user.owner?(@page) && @user.has_role?(:pages, :edit) #=> true | false
Default method for ownership checking is not suitable for me
If default method for ownership checking is not suitable for you, you can overwrite it or create your own
class User < ActiveRecord::Base
include TheRole::Api::User
# Just overwrite default `owner?(object)`
def owner?(object)
if object.is_a?(Article)
# code for ownership checking
else
# or call default version
super
end
end
def is_owner_of?(object)
# code
end
has_many :pages
end
Now you can check something, for instance:
@user.owner?(@article) #=> true | false
@user.owner?(@page) #=> true | false
or
@user.is_owner_of?(@page) && @user.has_role?(:pages, :edit) #=> true | false
@user.is_owner_of?(@article) && @user.has_role?(:articles, :edit) #=> true | false
owner_required method and controllers
Method owner_required based on method owner?(object) and variable @owner_check_object
If you want to use your own ownership checking method, you should to overwrite method owner_required to meet your needs.
You can do something like this:
Model
class User < ActiveRecord::Base
include TheRole::Api::User
def is_owner_of?(object)
# code
end
has_many :pages
end
Application controller
class ApplicationController < ActionController::Base
include TheRole::Controller
private
def for_ownership_check obj
@owner_check_object = obj
end
def my_special_ownership_check
role_access_denied unless current_user.try(:is_owner_of?, @owner_check_object)
end
end
and after in Pages controller
class PagesController < ApplicationController
before_action :login_required, except: [:index, :show]
before_action :role_required, except: [:index, :show]
before_action :set_page, only: [:edit, :update, :destroy]
before_action :my_special_ownership_check, only: [:edit, :update, :destroy]
# ... code ...
private
def set_page
@page = Page.find params[:id]
for_ownership_check(@page)
end
end