Validation of field with if option Mongoid - ruby-on-rails

I have a model with validations and I want to make a validation that only is checked if another field in that same form is true (its a boolean). I am having trouble with the syntax of this validation. So far I have
class Reportapproval
include Mongoid::Document
field :manager_requested, type: Mongoid::Boolean, default: false
field :disclosure_acceptance, type: Mongoid::Boolean, default: false
validates_acceptance_of :disclosure_acceptance, if: :manager_requested == true, :accept => true
end
What is the proper syntax so that this validation is only checked if the manager_requested field is set to true.
P.S. Is it possible to check the manager_requested field if this is being created at the time of input.

Try using a lambda or passing the method
validates_acceptance_of :disclosure_acceptance, if: lambda { manager_requested? }
or
validates_acceptance_of :disclosure_acceptance, if: :manager_requested?

Related

Graphql-Ruby Mapping using Active Record

I am completely new to using Rails, I'm trying to create a basic crud application using ruby-graphql to do a simple find query with active record to a sqlite3 database.
I set up a user type
class UserType < Types::BaseObject
description "A user type "
field :id, ID, null: false
field :username, String, null: false
field :email, String, null: false
field :email_confirmed, Boolean, null:false
field :first_name, String , null:false
field :last_name, String, null:false
field :biography, String, null:true
field :avatar, String, null:true
field :created_at, GraphQL::Types::ISO8601DateTime, null:false
field :updated_at, GraphQL::Types::ISO8601DateTime, null:false
end
Then I setup the query :
field :user, UserType, null:false,
description: "Get a single user" do
argument :username, String, required: true
end
def user(username:)
User.find(username)
end
My query is :
{
user(username:"test"){
username
}
}
I get the following error :
{
"error": {
"message": "no implicit conversion of #<Class:0x000000000b975440> into Hash",
"backtrace": [
"C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/graphql-1.9.13/lib/graphql/schema/field.rb:519:in `block in resolve'",
If anyone could help me I would really appreciate it.
How do I do this conversion in Ruby / Rails?
Turns out there was an issue with Ruby gem I was using upgraded to the new gem and it solved the problem. See - https://github.com/rmosolgo/graphql-ruby/issues/2537

Minitest for testing presence and allow_nil for the same attribute

I want to test a model attribute where it has presence as true, but also allow nil value. How can I test this? I made an example bellow:
# Person model
belongs_to :city
validates :city_id, presence: true, :allow_nil => true
I was trying to test with:
test "should permit nil for city_id" do
#person.city_id = nil
assert #person.valid?
end
What I got in console:
Expected false to be truthy.
I found the answer. The test was failing because it was missing a argument in belongs_to:
# Person model
belongs_to :city, optional: true
validates :city_id, presence: true, :allow_nil => true
The argument Optional allows nil value to foreign key.

Rails Field Validation Based on Value of Another Field

I need to validate that the value of a field (:discount) is one of an array of strings. The :discount field can also be blank UNLESS the :type field is 'FixedDeal' (STI)
validates :discount, inclusion: {in: VALID_DISCOUNTS}, allow_blank: true unless :type == 'FixedDeal'
The above code works to validation the value of :discount, but allows the field to be blank even if the type is 'FixedDeal'.
On your FixedDeal class add the following validation:
validates_presence_of :discount
That should work for you.

Updating record with Mongoid in Rails

I am testing this from rails console:
Credential.last.token => nil
Credential.last.update_attribute :token, '123' => true
Credential.last.token => nil
Here is my class:
class Credential
include Mongoid::Document
include Mongoid::Timestamps
field :_id, type: String
field :user_id, type: Integer
field :code, type: String
field :provider, type: String
field :token, type: String
end
What am I doing wrong?
If you have identity map enabled you'll need to wrap that in
Mongoid.unit_of_work { Credential.last.token }
Mongoid caches the queries. It is not a problem for web requests, but in the console you won't see the change unless you do it in the unit of work block, or restart the console (not just a reload)
I had to put
attr_accessor :token, ...

problem with passing booleans to update_attributes

I've got the following Model:
class GuestCatering < ActiveRecord::Base
# Validation
validates :name, :presence => true
validates :order_number, :presence => true
validates :orderable, :presence => true
end
But when I'll try to update an existing GuestCatering with the following code:
guest_catering.update_attributes(:orderable => false)
The guest catering variable is a valid GuestCatering object.
The guest_catering object has errors after the update, like that:
<{[:orderable, ["can't be blank"]]=>nil}>
But when i pass a orderable => true, everything is fine and no errors.
What's wrong here, why can't i set orderable to false?
Your model is actually behaving exactly as you told it to, through your use of validates :orderable, :presence => true
There's little point validating the presence of a boolean flag - it's going to be true, nil or false - and in Ruby world, nil and false have the same semantic value when it comes to boolean logic.
Internally, validates :presence relies on the value of the attribute being checked to return false when blank? is called. And, in Rails (with ActiveSupport), false.blank? evaluates as true - which means that your field is failing the validation.
Simply remove that validation and everything will work as expected.
Like Dan Cheail already said in his answer, a nil and false boolean is semantically the same thing.
But, if you really need to validate it (not allowing nil), you can always do :
validates_inclusion_of :orderable, :in => [true, false]
Instead of validates :presence => :true, you should write your migrations with the default value like this:
t.boolean :orderable, :default => 0
I assume your default value should be false. If true, use 1 as default. Then it will set the default value in database. So, you can omit the validation check.
The reason you cannot use validates :presence is answered by #dan. Presence means not blank and Rails use .blank? function for this and false.blank? is true

Resources