What I need if some user has an attribute, this will not need to be confirmed.
I've seen a couple of post about this but I cannot understand it (i'm kinda newbie in Rails).
In my user.rb
def confirmation_required?
if self.name == 'Joe'
false
end
end
I tried that out but nothing happens, is like always is false. I saw another post with this code:
def confirmation_required?
!confirmed?
end
#Put your conditions and job's done !
but how can I access to user data from my user.rb (model) Note that the user comes from HTTP Post request.
Can somebody help me?
Thanks
EDIT
Also I could just re-write Devise::RegistrationsController to something like this:
class RegistrationsController < Devise::RegistrationsController
def create
super do
if resource.name == 'Joe'
resource.skip_confirmation!
resource.save
end
end
end
end
Do you think this could solve it?
Thanks.
In your user model you can conditionally call skip_confirmation! in your before_save callback
class User < ActiveRecord::Base
before_save :skip_confirm # arbitrary method name
def skip_confirm
if self.name == 'Joe'
skip_confirmation!
end
end
end
or, you can use a block on before_save
class User < ActiveRecord::Base
before_save -> do
if self.name == 'Joe'
skip_confirmation!
end
end
end
Related
How to use scopes, defined in the model, in my Pundit policy?
In my model I have a scope:
scope :published, ->{ where.not(published_at: nil )}
And in my Pundit policy I have
class CompanyPolicy < ApplicationPolicy
def index?
true
end
def create?
user.present?
end
def new?
true
end
def show?
true
end
def update?
user.present? && user == record.user
end
end
How can I use my scope in the Pundit policy? I would like to show it only if it's "published", something like this, which doesn't work at the moment:
class CompanyPolicy < ApplicationPolicy
def show
record.published?
end
end
Scopes are Class methods, you can't call them on instances.
You have to define a published? instance method too:
def published?
published_at.present?
end
You could use the scope if you ask if the record exists on the given scope with:
User.published.exists?(user.id)
And it will return true if the scope includes the user id, but I wouldn't recommend that, it requires an extra query to the database to get something that you can know from the user instance you already have.
I'm struggling with some kind of issue. I have a rails model (mongoid).
class User
include Mongoid::Document
include ActiveModel::SecurePassword
validate :password_presence,
:password_confirmation_match,
:email_presence,
field :email
field :password_digest
def password_presence
end
def email_presence
end
def password_confirmation_match
end
end
My goal is to call validations depends on which decorator I will use. Let's say I've got two decorators:
class PasswordDecorator < Draper::Decorator
def initialize(user)
#user = user
end
end
def RegistraionDecorator < Draper::Decorator
def initialize(user)
#user = user
end
end
So now when I create/save/update my user object inside RegistraionDecorator I would like to perform all validation methods.
RegistraionDecorator.new(User.new(attrbiutes))
But when I will do it inside PasswordDecorator I want to call for example only password_presence method.
PasswordDecorator.new(User.first)
When I move validations to decorator it won't work cuz its different class than my model.
How can I achieve that?
Try to use a Form Object pattern instead.
Here is an example (from a real project) of how it could be done with reform.
class PromocodesController < ApplicationController
def new
#form = PromocodeForm.new(Promocode.new)
end
def create
#form = PromocodeForm.new(Promocode.new)
if #form.validate(promo_params)
Promocode.create!(promo_params)
redirect_to promocodes_path
else
render :edit
end
end
private
def promo_params
params.require(:promocode).
permit(:token, :promo_type, :expires_at, :usage_limit, :reusable)
end
end
class PromocodeForm < Reform::Form
model :promocode
property :token
property :promo_type
property :expires_at
property :usage_limit
property :reusable
validates_presence_of :token, :promo_type, :expires_at, :usage_limit, :reusable
validates_uniqueness_of :token
validates :usage_limit, numericality: { greater_or_equal_to: -1 }
validates :promo_type, inclusion: { in: Promocode::TYPES }
end
Bonus: The model does not trigger validations and much easy to use in tests.
I have a Sequel model like this:
class User < Sequel::Model
include Notificatable
def validate
super
validates_presence [:email]
end
end
# concerns/notificatable.rb
module Notificatable
extend ActiveSupport::Concern
included do
def validate
super
validates_presence [:phone]
end
end
end
And here I got a problem: Notificatable validate method overrides the same method in the User model. So there is no :name validations.
How can I fix it? Thanks!
Why use a concern? Simple ruby module inclusion works for what you want:
class User < Sequel::Model
include Notificatable
def validate
super
validates_presence [:email]
end
end
# concerns/notificatable.rb
module Notificatable
def validate
super
validates_presence [:phone]
end
end
I want to be able to write a comment as a guest or as a registered user with devise.
My comment model contains :title, :content, :user_id, :guest_email, :guest_website and :write_as_guest as a boolean.
I wanted to validate the presence of :guest_email only when no user is signed_in. But I think I'm not going in the good direction.
I'm managing the form with AJAX/jQuery and I wanted to have a guest form where :content and :guest_email are necessary fields. In another hand, I want to have the user form where only the :content is necessary.
Here is how I tried to go for it.
class Comment < ActiveRecord::Base
before_validation :set_write_as_guest
belongs_to :user
validates_presence_of :content
validates_presence_of :guest_email, :if => :write_as_guest?
private
def write_as_guest?
self.write_as_guest
end
def set_write_as_guest
if user_signed_in?
self.write_as_guest = false
else
self.write_as_guest = true
end
end
end
It seems that user_signed_in? method needs before_filter :authenticate_user! then I have the following in my comments_controller
before_filter :authenticate_user!, :only => :create
But however I don't want to authenticate to create because that's a guest...
So if somebody would be able to propose me a way to write as a guest or as a user, that would be really appreciated.
Thx
You can do a custom validation like this
class Comment < ActiveRecord::Base
validate :guest_commentator
def guest_commentator
user = User.find(user_id)
self.errors.add(:user_id => "some error message here ") unless user.nil?
end
end
I have Post model with published? field and some authorization system which defines admin? method inside ApplicationController.
I want to restrict access to unpublished posts and show them only to administrator.
I tried to define a scope accessible to return only published posts to users, but all posts for administrator.
scope :published, where(:published => true)
def self.accessible
admin? ? all : published
end
The problem is that admin? method can't be accessed inside the model. What is the best way to implement what I want?
# option 1
class Post < ActiveRecord::Base
def self.accessible_to user
user.admin? ? all : published
end
end
class PostsController < ApplicationController
def index
#posts = post.accessible_to current_user
end
end
# option 2
class Post < ActiveRecord::Base
def self.accessible is_admin
is_admin ? all : published
end
end
class PostsController < ApplicationController
def index
#posts = post.accessible admin?
end
end
One way, but not so abstract.
def self.published_unless(condition)
condition ? all : published
end
Post.published_unless(admin?)