Rails merit-gem cannot score points on confirmations - ruby-on-rails

I tried following the Wiki about the badge grant on confirmation but no luck. Is it supported for points as well? it doesn't explicitly mention in the Wiki.
[merit] no target found: uninitialized constant Users::Confirmation
Did you mean? Users::ConfirmationsController.
My devise routes:
devise_for :users, controllers: {
sessions: 'sessions',
omniauth_callbacks: 'users/omniauth_callbacks',
confirmations: 'users/confirmations',
passwords: 'passwords'
}
My confirmations controller:
module Users
class ConfirmationsController < Devise::ConfirmationsController
layout 'new_confirmation', only: %i[new create]
layout 'edit_confirmation', only: %i[edit update]
def show
super
#confirmation = resource # Needed for Merit / Must be AFTER the super
end
My Points rules:
module Merit
class PointRules
include Merit::PointRulesMethods
def initialize
score 1_000_000_000, on: 'users/confirmations#show', category: 'account_activity', &:confirmed?
end
end
end

Related

Disable rails_best_practices RestrictAutoGeneratedRoutes for devise scope routes

To limit devise auto generated routes, I have this in my route file...
## config/routes.rb
# Restrict auto generated devise routes
devise_scope :user do
resource :users,
only: [:new, :create, :edit, :update],
controller: 'users/registrations',
path_names: { new: 'sign_up' },
as: :user_registration
end
Controller:
## app/controllers/users/registrations_controller
module Users
# Copied by `devise` generator so we could override things.
class RegistrationsController < Devise::RegistrationsController
def new
# some logic
end
def create
# some logic
end
# # Overriding and call to `super` for these two method removes unused routes warning, I don't want this
# # rubocop:disable Lint/UselessMethodDefinition
# def edit
# super
# end
# def update
# super
# end
# # rubocop:enable Lint/UselessMethodDefinition
rails_best_practices linter is giving warning restrict auto-generated routes users (only: [:new, :create]) if I don't override the edit & update methods in RegistrationsController.
Is there a way to disable RestrictAutoGeneratedRoutesCheck for those routes?
Or what would be the most feasible way to resolve this warning? Thank you.
What about a custom rails_best_practices.yml with a tweaked RestrictAutoGeneratedRoutesCheck entry? See: https://github.com/flyerhzm/rails_best_practices
Go to rails_best_practices.yml and you can apply the ignored_files option on any rule by giving a regexp or array of regexp describing the path of the files you don't want to be:
In your case RestrictAutoGeneratedRoutesCheck{ignored_files: 'routes.rb'}.

How to have two different portals with devise?

This is my routes.rb:
scope '/staff' do
authenticated :staff_member do
root to: 'staff/schedule_entries#index'
end
unauthenticated :staff_member do
root to: 'staff/chains#index'
end
scope '/:chain_id', constraints: StaffChainConstraint do
devise_for :staff_members, path: '', controllers: {
sessions: "staff/sessions",
passwords: "staff/passwords",
}, only: [:sessions, :passwords]
end
end
scope '/franchisee' do
authenticated :staff_members do
root to: 'franchisee/locations#edit'
end
unauthenticated :staff_members do
root to: 'franchisee/chains#index'
end
scope '/:chain_id', constraints: StaffChainConstraint do
devise_scope :staff_member do
get 'sign_in', to: 'franchisee/sessions#new', as: :new_franchisee_session
post 'sign_in', to: 'franchisee/sessions#create', as: :franchisee_session
end
end
end
The issue I'm running into is after signing from the page franchisee/:chain_id/sign_in, it keeps redirecting to staff/schedule_entries#index instead of franchisee/locations#edit. What am I missing to make this work?
Edit: Here's my franchisee/sessions controller:
# frozen_string_literal: true
module Franchisee
class SessionsController < Devise::SessionsController
helper_method :current_brand, :current_chain
before_action :configure_sign_in_params, only: [:create, :new]
protected
def respond_to_on_destroy
path = if current_admin
admin_root_path
else
after_sign_out_path_for(resource_name)
end
redirect_to path
end
def current_chain
#current_chain ||= Chain.find_by!(slug: params[:chain_id])
end
def current_brand
current_chain.brand
end
def configure_sign_in_params
devise_parameter_sanitizer.permit(:sign_in, keys: [:username, :password])
end
def set_raven_context
Raven.tags_context(app: 'franchisee')
Raven.user_context(
type: 'franchisee',
username: params.dig(:staff_member, :username),
brand_slug: current_brand&.slug,
chain_slug: params[:chain_id],
)
end
end
end
I made sure this controller is hit when submitting the sign in form from the page franchisee/:chain_id/sign_in. I also tried to fiddle around with after_sign_in_for but wasn't able to figure out a good way for it to tell between staff and franchisee.

Devise - creating users only by admin

I'm creating an app where I need only admins to create new users:
routes.rb:
devise_for :users, :skip => [:registrations]
resources :users
root 'dashboard#index'
users_controller.rb
# GET /users/1/edit
#def edit
#
#end
# POST /users
# POST /users.json
def create
build_resource(sign_up_params)
respond_to do |format|
if resource.save
format.html { redirect_to user_path(resource), notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: user }
else
clean_up_passwords resource
respond_with resource
end
end
end
When I open http://localhost:3000/users/new
I got this error:
AbstractController::ActionNotFound at /users/new
Could not find devise mapping for path "/users/new".
This may happen for two reasons:
1) You forgot to wrap your route inside the scope block. For example:
devise_scope :user do
get "/some/route" => "some_devise_controller"
end
2) You are testing a Devise controller bypassing the router.
If so, you can explicitly tell Devise which mapping to use:
#request.env["devise.mapping"] = Devise.mappings[:user]
What is wrong there? Thank you a lot!
The problem is that you're confusing Devise functionality with that of your app:
#config/routes.rb
resources :users #-> nothing to do with devise
When you create a user, you're using the devise build_resource helper. Problem being that this will require devise functionality, which is not going to happen for users_controller.
To use sign_up_params or build_resource, you'll have to scope your routes to a devise controller (so all the available session data is there)...
#config/routes.rb
devise_for :user, skip: [:registrations]
devise_scope :user do
resources :users, path: "", only: [:new, :create], controller: "registrations" #-> url.com/users/new
end
This way, you'll be able to override the standard Devise::RegistrationsController with your own code:
#app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
before_action :authenticate_user!
before_action :check_admin
def create
build_resource(sign_up_params)
...
end
private
def check_admin
redirect_to root_path unless current_user.admin?
end
end
--
What I would recommend is either removing the Devise functionality from your users controller, or overriding the registrations controller so that only an admin can create a user (which it seems you're trying to do already).

How to handle routes in rails api

I am learning api on rails,and my code is below
routes.rb
require 'api_constraints'
Rails.application.routes.draw do
devise_for :users
namespace :api, defaults: { format: :json }, constraints: { subdomain: 'api' }, path: '/' do
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
resources :users, :only => [:show]
end
end
end
users_controllers.rb
class Api::V1::UsersController < ApplicationController
respond_to :json
def show
respond_with User.find(params[:id])
end
end
when I run the rails server with localhost:3000/users/1 then It gives me the error No route matches
Then i checked routes using rake routes and it is included in my routes
`api_user GET /users/:id(.:format) api/v1/users#show'
but i don't know why it gives me the error
api_constraints.rb
class ApiConstraints
def initialize(options)
#version = options[:version]
#default = options[:default]
end
def matches?(req)
#default || req.headers['Accept'].include?("application/vnd.marketplace.v#{#version}")
end
end
`
Try the following:
api.lvh.me:3000/api/v1/users/1
You've setup a constraint that requires an api sub domain. You'll need to remove the constraint to make the following work:
lvh.me:3000/api/v1/users/1
Note: lvh.me points to 127.0.0.1

Rails devise with scope fails with InvalidAuthenticityToken

We are using Rails 4.2.1 and the latest version of Devise (3.4.1) although I believe the same error occurs with other versions.
Ever since we added scope to routes.rb:
scope '/admin' do
root to: "places#index"
devise_for :users, controllers: { registrations: "users/registrations" }
...
Devise fails to sign in or sign out with the following error:
ActionController::InvalidAuthenticityToken at /admin/users/sign_out.
Everything works perfectly fine as long as we remove the scope.
We tried using custom routes with devise but nothing helped.
registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
before_action :configure_permitted_parameters
protected
def configure_permitted_parameters
devise_parameter_sanitizer.for(:sign_up).push(:first_name, :last_name, :organization)
end
end
You should try to define your scope for devise as following:
devise_for :users
devise_scope :user do
scope '/admin' do
get "/your_route" ...
end
end
And for the rest of the routes apply "/admin" scope separately.

Resources