removing mask before saving in DB - ruby-on-rails

I have a JavaScript to mask a value in my form. I'm trying to remove this mask before save it in db, but i have problems
model:
class Partner < ApplicationRecord
belongs_to :address, dependent: :destroy
has_many :dependents
accepts_nested_attributes_for :address
# Validations #
# Validates presence of some attributes #
validates_presence_of :registry_number, :name, :secretary, :position, :base_salary, :rg, :cpf, :birthday, :email, :union_admission, :start_date
validates :registry_number, numericality: {only_integer: true}
# Validates the size of some attributes #
validates :registry_number, length: {maximum: 5}
validates :cpf, length: {is: 11}
validates :rg, length: {is: 9}
validates :phone_number, length: {maximum: 11}
:cpf.gsub(/[.\/]/, '')
end
error
undefined method `gsub' for :cpf:Symbol
Extracted source (around line #18):
16
17
18
19
20
:cpf.gsub(/[.\/]/, '')
end
How can I solve it?

As the error message tells you, the line :cpf.gsub(/[.\/]/, '') is the problem. Firstly, you're calling the method gsub on a symbol :cpf, and the method doesn't exist . Try it in irb.
Secondly, even if this wasn't the case, it wouldn't make any difference – the code is only going to be run once when the class is loaded and wouldn't be run each time you save a new Partner. You need to add a before_validation callback to run your code each time you create a new object, which would look something like this:
class Partner
#...
before_validation :unmask_cpf
#...
private
def unmask_cpf
cpf = cpf.gsub(/[.\/]/, '')
end
end

gsub is a method on strings, so you can call .to_s on the symbol first.

Related

how to validate presence of element in absence of another in rails

I have this model that validates presence: true for both post_id and user_id but I want it to validate the presence of one if the other is absent.
here is the validation :
validates :user_id, :comment_id, :post_id, presence: true
If you have any questions don't hesitate to ask
validates_presence_of :post_id, unless: :user_id
validates_presence_of :user_id, unless: :post_id
Since ActiveRecord automatically creates question mark methods for each of your model's attributes, you could also do:
validates_presence_of :post_id, unless: :user_id?
validates_presence_of :user_id, unless: :post_id?
:post_id? or user_id? returns false for nil or blank.
Simple Update thanks to rubocop, when i tried to use this logic, rubocop auto correct my line actually
C: [Corrected] Rails/Validation: Prefer the new style validations validates :column, presence: value over validates_presence_of.
validates_presence_of :<model_name>, unless: :
it basically converted this version
validates_presence_of :<model_name>, unless: :<condition>
To this:
validates :<model_name>, presence: { unless: :<condition> }

how to include a class which is not a model in controller

I have added class ContactRequest in home_helper.rb
module HomeHelper
class ContactRequest
include ActiveModel::Model
attr_accessor :name, :email, :phone, :message, :captcha
validates :name, presence: true,length: {in:2..255}
validates :email, presence: true, length: {in:6..255}
validates :message, presence: true
validates :phone, presence: true
validates :captcha, presence: true
end
end
This class basically is to be used to bind dat from a JSON POST to an object which then I can use for
Verifying Captcha
Sending the contact information from this object as an email via SendGrid
hence, I do not have any needs to persist the information.
However I get an error when the relevant method of the controller is called
def contact
#contactReq = ContactRequest.new(JSON.parse(params[:json]))
logger.debug "ContactRequest: #{#contactReq.attributes.inspect}"
for this line I see in the logs
NameError (uninitialized constant HomeController::ContactRequest):
app/controllers/home_controller.rb:6:in `contact'
isn't the home_helper available to the view and this controller? Or should I put this class in concerns directory?
You need to add the module name in front of the classname HomeHelper:
def contact
#contactReq = HomeHelper::ContactRequest.new(JSON.parse(params[:json]))
...
end

I have two before_validation callbacks. Which one gets executed first?

Here is my company model which has geocoding. Basically, I want to make sure that the add_full_address method is called before the geocoding method because the geocoding method depends on the full_address. How do I get this to work? Are the validations run in order that they are written? I need them both to happen before validations are run because I want to verify that the latitude and longitude columns are populated because otherwise... I want the save to fail.
class Company < ActiveRecord::Base
include ActiveModel::Dirty
validates :name, :organization, :title, :state, :city, presence: true
validates :email, presence: true, length: { maximum: 255 },
format: { with: /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i, }
validates :latitude , numericality: { greater_than_or_equal_to: -90, less_than_or_equal_to: 90 }
validates :longitude, numericality: { greater_than_or_equal_to: -180, less_than_or_equal_to: 180 }
before_validation :add_full_address
before_validation :geocode, if: ->(obj){(obj.city_changed? || obj.state_changed?)}
geocoded_by :full_address do |obj, results|
if geo = results.first
obj.latitude = geo.latitude
obj.longitude = geo.longitude
end
end
def add_full_address
self.full_address = "#{city}, #{state}"
end
def d3_coordinates
slice(:longitude, :latitude)
end
end
Take a look at this: ActiveRecord::CallBacks This will give you all the callbacks you can use. Also ruby being a synchronous language, it will run from top to bottom, but of course the callbacks are run before the validations in this case.
According to the doc, validators get executed in the order that they are defined.
All before_validation callbacks will be called prior to ANY validators

Rails Admin NoMethodError in RailsAdmin::Main#delete

I have model Order:
class Order < ActiveRecord::Base
has_one :shipping_address
has_and_belongs_to_many :books
validates :first_name, :surename, :email, :street1, :country, :zipcode, presence: true
validates_format_of :email, :with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
validates :zipcode, numericality: true
accepts_nested_attributes_for :shipping_address
end
and model Book:
class Book < ActiveRecord::Base
DEFAULT_PRICE = 55.15
NEXT_BOOK_PERCENT = 5
has_and_belongs_to_many :pages
has_and_belongs_to_many :orders
validates :name, presence: {message: "Name can't be blank."}
validates_length_of :name, minimum: 3, maximum: 12, message: "Sorry, we can't create this book right now. Please contact us for further information."
validate :same_letter_validation
validate :validates_for_non_alphabetic
before_save :compile
#......
end
Also I have table books_orders (book_id, order_id)
When I try do delete order from RailsAdmin panel I get next error:
NoMethodError in RailsAdmin::Main#delete
undefined method `orders_books' for #
It says that error in this line:
- #abstract_model.each_associated_children(object) do |association, child|
Have you defined that "orders_books" method anywhere in your code? If so, can you please add it to your question. If you haven't, then the root cause of your issue is just that, that you're calling the "orders_books" method but it is not yet defined
Given that you reference "#books_orders" in your question, I believe it likely that you just swapped "books_orders" and "orders_books" at some point in your code
Thanks. It's bug of a Rails 4.1.1. I have update it to 4.1.4 and all works OK.

Strong parameters in Ruby

I'm getting the error message about strong parameters. I think it's just that rails 4 doesn't use attributes anymore. the code for my toy.rb is:
class Toy < ActiveRecord::Base
attr_accessible :name, :price, :vendor
validates :name, :presence => true
validates :price, :presence => true
validates :price, :numericality => true
validates :vendor, :presence => true
end
how can I change this to strong parameters?
EDIT: I used a different rb i changed it to employees and this is what I have:
class Employee < ActiveRecord::Base
params.require(:employee).permit(:first, :last, :salary, :salary, :ssn)
validates :first, :presence => true
validates :last, :presence => true
validates :salary, :presence => true
validates :salary, :numericality => true
validates :ssn, :presence => true
end
It's still telling me "ndefined local variable or method `params' for #"
The code you need is
params.require(:toy).permit(:name, :price, :vendor)
You will put this in your controller. Typically, you create a private method:
def create
Toy.create(toy_params)
end
private
def toy_params
params.require(:toy).permit(:name, :price, :vendor)
end
See http://guides.rubyonrails.org/getting_started.html#saving-data-in-the-controller for more information.
Edit
I think I might have misled you with my original answer. The code goes in the controller, not the model.
Strong params are designed to help your controller send specific data to your model. It's meant to protect your app against unauthorized data being passed:
#app/controllers/toys_controller.rb
Class ToysController < ActiveRecord::Base
def new
#toy = Toy.new #-> creates a blank AR object
end
def create
#toy = Toy.new(toys_params) #->creates new AR object (populating with strong params)
#toy.save
end
private
def toys_params
params.require(:toys).permit(:your, :params, :here)
end
end

Resources