Devise unscoped authorization in Rails

2019-08-09 02:48发布

问题:

I have a model like this:

class Engineer < ActiveRecord::Base
  default_scope { is_published }
  scope :is_published, -> { where(is_published: true) }
end

Engineers can be authorized on the site via GitHub. And I want to give ability to authorize on the site for unpublished Engineers too. There are such filters in some controllers:

before_action :authenticate_engineer!, only: [:show]

But now after successfull authorization Engineer still can't pass these filters. How to say Devise that he should search between unscoped Engineers? Think, I should override some Devise method...

回答1:

Solution was to override this Devise method in the Engineer.rb:

def self.serialize_from_session(key, salt)
  Engineer.unscoped {super}
end


回答2:

If I'm understanding you correctly, you want:

  • authenticated engineers to be able to view unpublished engineers
  • non-authenticated engineers to not be able to view them

Do not use a default scope, and do something like this instead:

# engineer.rb
class Engineer < ActiveRecord::Base
  scope :published, -> { where(is_published: true) }
end

And in your controller:

# engineers_controller.rb
def show
  @engineers = engineer_signed_in? ? Engineer.all : Engineer.published
end

Basically you're showing all engineers for authenticated engineers, and only the published ones for those not signed in using Devise.