简体   繁体   中英

How to enable post deletion on social site by devise admin users?

I've been working on a social link aggregator site and have run into a wall with regards to admin permissions.

Currently all users can edit and destroy their own posts (admins included) but an error is thrown when an admin tries to delete a post created by another user.

While I'm fairly well versed in ruby my rails knowledge is severely lacking so it may well be something extremely simple staring me in the face.

When attempting to edit a post the error is: undefined method `model_name' for TrueClass:Class

When attempting to delete a post the error is: undefined method `destroy' for true:TrueClass

Here are relevant parts of my links_controller.rb:

  def update
respond_to do |format|
  if @link.update(link_params)
    format.html { redirect_to @link, notice: 'Link was successfully updated.' }
    format.json { render :show, status: :ok, location: @link }
  else
    format.html { render :edit }
    format.json { render json: @link.errors, status: :unprocessable_entity }
      end
  end
end

  def destroy
@link.destroy
respond_to do |format|
  format.html { redirect_to links_url, notice: 'Link was successfully destroyed.' }
  format.json { head :no_content }
    end
end

    def authorized_user
  @link = current_user.links.find_by(id: params[:id]) || current_user.admin?
  redirect_to links_path, notice: "Not authorized to edit this link" if @link.nil?
 end

The user model:

class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable
has_many :links
has_many :posts
acts_as_voter
validates :twitter, :twitter => { :format => :username_with_at,        allow_blank: true }
validates :avatar_url, :url => { allow_blank: true }
 end

And the admin model:

class Admin < ActiveRecord::Base
devise :database_authenticatable, :trackable, :timeoutable, :lockable
end

If you need any more information I'll be happy to provide it, alternatively if any of the code I've posted is irrelevant to the issue let me know and I'll remove it from the post.

@link will be true if current_user is admin, it's not correct, @link should be an instance of Link

@link = current_user.links.find_by(id: params[:id]) || current_user.admin?

You should use an authorization gem to check permission such as action_access, cancan, cancancan, pundit,...

problem is the following line

@link = current_user.links.find_by(id: params[:id]) || current_user.admin?

here if the user is admin then the value of @link will be 'true'

so @link.destroy becomes true.destroy which is not a valid function

undefined method `model_name' for TrueClass:Class

This basically means you've populated a variable with true instead of an object. You know this already; it should direct you towards what to look for to identify the problem:

@link = current_user.links.find_by(id: params[:id]) || current_user.admin?

The error here is that you're calling current_user.admin? . Because your initial argument is returning false, Ruby is referring to the last. the admin? method must be returning true .

--

Authorization

The fix for this is something called Authorization .

You'll probably know this already; in the sense of Rails, authorization is not handled very well at all at the moment. The best implementations have been CanCan by Ryan Bates (of Railscasts fame).

In short, what you need is some sort of system which examines who you are, and allows you to perform an action based on your credentials.

If you handled this manually, you'd do this:

@link = current_user.links.find_by(id: params[:id]) || (Link.find(params[:id]) if current_user.admin?) #-> not tested!!!

If you used something something like CanCan (now updated to CanCanCan ) you could use:

#app/controllers/your_controller....
def destroy
  @link = Link.find params[:id]
  @link.destroy if can? :destroy, @link
end

#app/models/ability.rb
class Ability
   include CanCan::Ability
   def initialize(user) 
       user ||= User.new # guest user (not logged in)
       can :manage, :all if user.has_role? :admin
       can [:update, :destroy], Link, user_id: user.id
   end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM