Search code examples
ruby-on-railsrubyruby-on-rails-4devisecancan

How can I make a rails authors resource a devise user?


I have setup a rails application with devise on it so users can register and login and they can add posts and other resources based on their roles(Admin,Teacher,Author,Pupil). Admin as access to everything and I am using gem 'cancan' for roles.

if user.role
        if  user.role.name == "Admin"
            can :manage, :all
        elsif user.role.name == "Teacher"
            can :manage, [Book, Story]
            can :read, [Book, Author, Story]
        elsif user.role.name == "Author"
            can :manage, [Book, Author]
            can :read, [Book, Author, Story]
        elsif user.role.name == "Pupil"
            can :manage, [Story]
            can :read, [Book, Author, Story]
        elsif user
            can :read, :all
        end
    else
        can :read, :all
    end

Currently Authors are just added to a book when you create the book. In the backend you just add authors as many as you like and then assign that to a book. If your an admin you can edit authors details and if your an author you can edit your own profile area in your author resource but there is no login for an author to do this at all.

What I want to know is: Is it easy to create a devise user type like author from authors already added to the backend or will they need to be created all over again?

=== Edit below here ====

user.rb

class User < ActiveRecord::Base
  belongs_to :role
  def confirmation_required?
    false
  end
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :confirmable


  has_attached_file :avatar, styles: {
        large: "600x450#",
        medium: "250x250#",
        small: "100x100#"
    }, :default_url => "/images/:style/filler.png"
  #validates_attachment_content_type :avatar, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
  validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
  validates :avatar, :email, :username, :password, presence: true

end

role.rb

class Role < ActiveRecord::Base
    has_many :users
end

author.rb

class Author < ActiveRecord::Base
    has_many :books, dependent: :destroy
    has_many :ideas, dependent: :destroy
    accepts_nested_attributes_for :books
    accepts_nested_attributes_for :ideas
    validates_uniqueness_of :name

    has_attached_file :avatar, :styles => { :large => "980x760", :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
    validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/


end

Thanks Mark


Solution

  • You don't need to create separate model(Author) just to handle author logins. Better approach will be using associations in this case.

     #user_role.rb 
    class UserRole < ActiveRecord::Base
      has_many :users
    end
    
     #user.rb 
    Class User < ActiveRecord::Base  
     belongs_to :user_role 
    end
    
    Typical user model attributes will be 
    User(id: integer, email: string, name:string, user_role_id:integer)
    user_role model attributes will be 
    UserRole(id: integer, role: string)
    
    UserRole.create(role: 'Admin') 
    UserRole.create(role: 'Teacher')
    UserRole.create(role: 'Author')
    UserRole.create(role: 'Pupil')
    
    then create your author( Let's assume the id for 'Author' role is 3)
    user = User.create(name: 'abc', email: '[email protected]', user_role_id: 3)
    

    now, use this user object and go for devise login.

    Now to list all the authors of our Application.

       #user.rb
          def self.all_authors
              User.select('users.id, users.name, user_roles.role AS USER_ROLE')
             .joins(:user_role).where(user_roles: {role: 'Author'})
          end
    

    Now to get all authors just give a call :

     User.all_authors #this will list all the users of type 'author'