Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NoMethodError when using Namespaces #195

Closed
treydock opened this issue Aug 18, 2014 · 2 comments
Closed

NoMethodError when using Namespaces #195

treydock opened this issue Aug 18, 2014 · 2 comments

Comments

@treydock
Copy link

Currently using gem 'pundit', github: 'elabs/pundit' in my Gemfile and have 'bundle show' outputing pundit (0.2.3 165c7f4). When testing my application in development I am occassionally running into an issue where my namespaced controller action throws the following error:

NoMethodError in Admin::AccountsController#review
undefined method `review?' for #<AccountPolicy:0x007fd2db587f68>

Is this a bug or a flaw in my code? Let me know what other information would be helpful to debug this. Below are what I hope to be the relevant bits of code.

app/models/account.rb

class Account < ActiveRecord::Base
...
end

app/controllers/admin/application_controller.rb

class Admin::ApplicationController < ApplicationController
  before_action :redirect_to_sign_in, unless: :user_signed_in?
  after_action :verify_authorized
  after_action :verify_policy_scoped, only: :index

end

app/controllers/admin/accounts_controller.rb

class Admin::AccountsController < Admin::ApplicationController
  before_action :set_account, only: [:show, :review]
  skip_after_action :verify_policy_scoped

  respond_to :html, :json

  # GET /accounts
  def index
    authorize Account
    respond_to do |format|
      format.html
      format.json { render json: AccountsDatatable.new(view_context) }
    end
  end

  # GET /accounts/1
  def show
    authorize @account
    respond_with(@account)
  end

  # GET /accounts/1/review
  # PATCH/PUT /accounts/1/review
  def review
    authorize @account
    if request.patch? or request.put?
      if @account.update(account_params)
        redirect_to admin_accounts_path, flash: { success: "Account request updated successfully" }
      else
        redirect_to review_admin_account_path(@account), flash: { error: @account.errors.full_messages.to_sentence }
      end
    else
      @account.reviewed_by = current_user
      @account.tamu_data = Account.tamu_data(@account.requested_username)
      respond_with(@account)
    end
  end

  private

  # Use callbacks to share common setup or constraints between actions.
  def set_account
    @account = Account.find_by_request_id(params[:id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def account_params
    params.require(:account).permit(:status_id, :username, :nodehours,
      :primary_group_id, :organization_id, :reviewed_by_id, :review_description,
      group_ids: []
    )
  end
end

app/controllers/accounts_controller.rb

class AccountsController < ApplicationController
  before_action :redirect_to_sign_in, unless: :user_signed_in?, only: [:new,:create,:show]
  after_action :verify_authorized, except: [:index,:access,:policies]

  respond_to :html

  # GET /accounts
  def index
    redirect_to access_accounts_path
  end

  # GET /accounts/access
  def access
  end

  # GET /accounts/policies
  def policies
  end

  # GET /accounts/new
  def new
    @account = Account.new
    authorize @account
    @account.submitted_by = current_user
    respond_with(@account)
  end

  # POST /accounts
  def create
    @account = Account.create(account_params)
    authorize @account
    @account.status = Status.unconfirmed

    if @account.save
      flash[:success] = "Account request created successfully"
      @account.send_confirmation_instructions
      redirect_to account_path(id: @account.request_id)
    else
      flash[:error] = @account.errors.full_messages.to_sentence
      redirect_to new_account_path
    end
  end

  # GET /accounts/:id
  def show
    request_id = params[:id]
    @account = Account.find_by_request_id(request_id)
    authorize @account
    respond_with(@account)
  end

  private

  # Never trust parameters from the scary internet, only allow the white list through.
  def account_params
    params.require(:account).permit(:firstname, :lastname, :email, :phone,
      :requested_username, :submitted_by_id, :requested_nodehours,
      :department, :classification_id, :status_id,
      :request_description, :hippa, :itar, :aup)
  end

end

app/policies/admin/account_policy.rb

class Admin::AccountPolicy < Admin::ApplicationPolicy
  def index?
    user.admin?
  end

  def show?
    index?
  end

  def review?
    user.admin? and record.status == Status.requested
  end

  def create?
    false
  end

  def new?
    create?
  end

  def update?
    false
  end

  def edit?
    update?
  end

  def destroy?
    false
  end

end

app/policies/admin/application_policy.rb

class Admin::ApplicationPolicy < ApplicationPolicy
  class Scope < Scope
    def resolve
      if user.admin?
        scope.all
      else
        nil
      end
    end
  end
end
@thomasklemm
Copy link
Collaborator

I think you're code looks fine, and since you're only running into this problem occasionally, my guess would be that Rails autoloading is not working as expected (or working as expected, but not working for us here). We're discussing pull this namespacing thing before releasing 0.3.0, I think this issue describes exactly why. Anyone please correct me if you spot some other issue.

@jnicklas
Copy link
Collaborator

Namespaces have been pulled, partially for this reason. See #178 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants