Model Validations with RefineryCMS - ruby-on-rails

Keep getting Syntax Error in Controller due to custom validations. Wondering how exactly I would implement custom validations within Refinery.
Error
/Users/bklane/Documents/code/codery/syrsp_two/vendor/extensions/quotes/app/models/refinery/quotes/quote.rb:18: syntax error, unexpected tIDENTIFIER, expecting keyword_end
validate :in_future?
quote.rb
module Refinery
module Quotes
class Quote < Refinery::Core::BaseModel
# require 'postmaster'
self.table_name = 'refinery_quotes'
attr_accessible :company, :due_by, :email, :f_name, :l_name, :phone, :pickup, :ship_city, :ship_line_1, :ship_line_2, :ship_contact, :ship_company, :ship_state, :ship_zip, :email_sent, :note, :position
alias_attribute :message, :note
alias_attribute :name, :company
# Add some validation here if you want to validate the user's input
# We have validated the first string field for you.
validates_presence_of :email, :phone, :f_name, :l_name
validates_inclusion_of :pickup, in: [true, false]
validates_format_of :email, :with => /\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i\
# validations not working below
validate :in_future?
# validate :parse_phone
# validate :validate_address
def in_future?
errors.add(:due_by, "Order cannot be due in the past") unless (due_by.present? && (1 === (due_by <=> Date.today)))
end
end
end
end

The trailing \ in your regular expression on line 17 is the cause of the syntax error.

Related

Rails - Object attributes accessible individually but not by inspect method

Sorry I'm new to rails but can't wrap my head around this one.
I have an Order object with various attributes - no references
In my controller I can print out the attributes individually via their attr_accessor and see them in the console via puts.
But when I call .inspect they are all nil! any suggestions?
class Order < ApplicationRecord
attr_accessor :name, :email, :phone, :date, :dessert_type, :size, :quantity, :dessert, :comments, :total
validates :name, :date, :quantity, presence: true
validates :quantity, numericality: { only_integer: true, greater_than: 0}
validate :contact_provided?
private
def contact_provided?
if :email.blank? || :phone.blank?
errors.add(:base, "Please provide either phone or email so we can contact you!")
end
end
end
Controller
def create_order
puts "create_order object"
#order = Order.new order_params
if #order.valid?
puts #order.inspect
#everything is null here
#order.attributes.each do |attr_name, attr_value|
puts "#{attr_name}: #{attr_value}"
end
#this prints out fine!
puts "dessert: #{#order.dessert}"
end
end
Parameters
Parameters: {"utf8"=>"✓", "authenticity_token"=>"randomtoken", "order"=>{"name"=>"jim", "email"=>"test#email.com", "phone"=>"12345678", "dessert_type"=>"Cake", "size"=>"25.0", "dessert"=>"Chocolate Caramel", "date"=>"2018-04-15", "quantity"=>"1", "comments"=>""}, "commit"=>"Submit Order"}
Any insight much appreciated!
That's because this line:
attr_accessor :name, :email, :phone, :date, :dessert_type, :size, :quantity, :dessert, :comments, :total
is overriding the Order attributes in the way Rails works with them. As working with Rails you don't need that declaration, so you can remove them as attr_accessor.
As Order is an ActiveRecord model, then the getters and setters are already generated by ActiveRecord for all of your object attributes.
What you're doing right now is defining all of your attributes, with the attr_accessor as virtual attributes which are attributes on the model that don't persist in the database, just "an attribute not corresponding to a column in the database".

removing mask before saving in DB

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.

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.

has_one, reject_if, and accept_nested_attributes_for still triggers validation

I'm trying to provide a place to set a single service login for an account, yet not require that the account owner enter the service login credentials every time the rest of the record is updated.
My understanding is that the :reject_if option on accepts_nested_attributes_for is the way to have the nested hash values ignored. Yet, in Rails 4.1, I'm getting a "password can't be blank".
I've traced through the nested_attributes code and it seems to properly ignore the values, yet nothing I do to avoid the update works. I've even deleted the web_service_user_attributes hash from the params passed to update, so I'm wondering if there is something else going on.
Am I understanding :reject_if correctly for a has_one association?
Parent model code:
class Account
has_one :web_service_user
accepts_nested_attributes_for :web_service_user, :allow_destroy => true, :reject_if => :password_not_specified, :update_only => true
def password_not_specified(attributes)
attributes[:password].blank?
end
end
Child model code:
class WebServiceUser
devise :database_authenticatable
belongs_to :account
validates_uniqueness_of :username
validates_presence_of :password, if: Proc.new{|wsu| !username.blank? }
end
Controller code:
def update
respond_to do |format|
if #licensee.update(account_params)
#etc...
end
private
def account_params
params.require(:account).permit(:name, :area_of_business, :address1, :address2, :city, :state_code, :zip, :website_url, :web_service_user_attributes => [:id, :username, :password, :_destroy])
end
Ok, it appears that my primary goof was trying to validate the presence of :password. I really wanted to validate the length of the password if it existed.
class WebServiceUser
devise :database_authenticatable
belongs_to :account
validates_uniqueness_of :username
validates_length_of :password, :minimum => 14, if: Proc.new { |u| !u.password.nil? }
end

Rails: is there a model shortcut for listing my many "attr_accessible" + "validates :presence => true" attributes?

In many of my rails models, I have a number of fields which are what I think of as "normal" model attributes, ie things which are set by the user, then later displayed, and are mandatory parts of a model instance. It seems kind of overly verbose to have to always do this:
class Person < ActiveRecord::Base
attr_accessible :name
attr_accessible :age
attr_accessible :height
validates :name, :presence => true
validates :age, :presence => true
validates :height, :presence => true
end
Ideally I'd like to just tell rails "everything but the auto-generated ID field should be validated present and accessible for mass assignment". How can I do that, given that it's said to be bad security practice to just make everything available for mass assignment?
Update: The existing way also seems bad in that I type my list of attributes twice, which is quite error prone.
Define your own class method, say on ActiveRecord::Base:
class ActiveRecord::Base
def self.validate_presence_and_make_accessible *args
attr_accessible *args
validates_presence_of *args
end
end
Then in your models:
class Person < ActiveRecord::Base
validate_presence_and_make_accessible :name, :age, :height
end
I suck at naming methods sometime, btw. Feel free to rename to something better.
A little less verbose way:
class Person < ActiveRecord::Base
attr_accessible :name, :age, :height
validates :name, :age, :height, :presence => true
end
Specifying only protected attributes:
class Person < ActiveRecord::Base
attr_protected :id
validates :name, :age, :height, :presence => true
end
This is simpler:
class Person < ActiveRecord::Base
attr_protected :id
validates_presence_of :name, :age, :height
end
And regarding your comment about security practice of mass assignments, I think you should read this: http://b.lesseverything.com/2008/3/11/use-attr_protected-or-we-will-hack-you

Resources