Using less than or greater validation in ruby on rails - ruby-on-rails

I have two models the first model is entry this is used with my controller entry to create a new request.. I need to validate range_days from entry is less than or equal to range from my second model empaccrl..But no matter what I do Still get an undefined method range...
My Entry Model
class Entry < ActiveRecord::Base
self.primary_key = 'id'
validates :indirect_id, presence: true, allow_blank: false
validates :leave_range, presence: true, allow_blank: false
validates :range_days, presence: true, allow_blank: false, length: { maximum: 2 }
# Really wish I could get this validation to work ..............
validates :range_days, :numericality => { :less_than_or_equal_to => :range }, :presence => true
belongs_to :empaccrl
attr_accessible :emp_id, :person_id, :emp_dept, :emp_no, :emp_first_name, :emp_last_name, :emp_mail_addr, :indirect_id, :mgr_no, :mgr_first_name, :mgr_last_name, :mgr_mail_addr, :leave_range, :employee_type, :seq_no, :range_days, :alt_mgr_name, :alt_mgr_addr, :alt_mgr_no
# This is for the validation
def range
empaccrl.range
end
end
My Empaccrl Model
class Empaccrl < ActiveRecord::Base
establish_connection :vdev
self.table_name = 'empaccrl'
belongs_to :entry
attr_accessor :range
end
My Entry Controller with create method and new
def new
#entry = Entry.new
respond_to do |format|
format.html# new.html.haml
format.xml { render :xml => #entry }
end
end
def create
params.permit!
#entry = Entry.new(params[:entry])
respond_to do |format|
if #entry.save
EntryMailer.submit_for_approval(#entry).deliver
format.html { redirect_to(entry_path( #entry ), :notice => 'Entry successfully created.') }
format.xml { render :xml => #entry, :status => :created, :location => #entry }
else
format.html { render :action => "new" }
format.xml { render :xml => #entry.errors, :status => :unprocessable_entity }
end
end
end
This is my entry table
ID NUMBER(38,0)
CREATED_AT DATE
UPDATED_AT DATE
EMP_ID VARCHAR2(255 BYTE)
EMP_NO VARCHAR2(255 BYTE)
EMP_FIRST_NAME VARCHAR2(255 BYTE)
EMP_LAST_NAME VARCHAR2(255 BYTE)
EMP_MAIL_ADDR VARCHAR2(255 BYTE)
INDIRECT_ID VARCHAR2(255 BYTE)
MGR_NO VARCHAR2(255 BYTE)
MGR_FIRST_NAME VARCHAR2(255 BYTE)
RANGE_DAYS NUMBER(38,0)
This is my Empaccrl table
PERSON_ID NUMBER(10,0)
IS_ACTIVE VARCHAR2(1 BYTE)
ACCRUAL_DATE DATE
RANGE NUMBER(10,0)
PROJECTED_ACCRUED NUMBER(12,5)
Any help is greatly appreciated my eyes are burning from staring at this for so long!!!!!

No way to do this using built-in validations. You need to write a custom one:
validates :range_days, :presence => true
validate :range_days_smaller_than_range, if: :range
private
def range_days_smaller_than_range
errors.add(:range_days, "LOL Nah! <Any error message or translation key here>") if range_days > range
end

I got it to work!!!!
This is how I got it to do what I wanted it to do thanks #BroiSatse for the help!
validate :range_days_smaller_than_range, if: :range
def range
range = Empaccrl.where("person_id = ? and is_active = ?", '14052', 'Y').pluck(:range).first
end
private
def range_days_smaller_than_range
errors.add(:range_days, "Sorry you don't have days for this request") if range_days > range
end
end

Related

Undefined method `build_for` for class in Rails

I have a simple app in which I want to allow the admin to create a new company. My create method in the controller is as follows:
def create
#company = Company.find_by({ name: company_create_params[:company_name] })
if #company.nil?
#company = Company.build_for(company_create_params)
else
return render :status => 200, :json => {
:error => true,
:reason => 'This company already exists in the database!'
}
end
if #company.save
return render :status => 200, :json => {
:success => true
}
else
return render :status => 500, :json => {
:error => true,
:reason => 'There was a problem adding the company'
}
end
end
private
def company_create_params
params.require(:company).permit( :company_name, :company_total_credits )
end
And my company model is:
class Company < ActiveRecord::Base
has_many :role
end
But every time I make an API post it gives me an error Undefined methodbuild_forfor class #<....>
Is it because of the has_many relationship? I don't want to add any value for the roles, rather I want them to be able to do it later on. Is there no way to fix this?
ActiveRecord doesn't provide a build_for method, hence the error.
You probably meant build, which is a method defined on collection associations. In this case, you probably want new or create since Company is a model, not an association.
Your whole action could be reduced significantly by following some conventions, by the way:
class Company < ActiveRecord::Base
has_many :roles
validates :company_name, uniqueness: true
end
# controller
def create
#company = Company.new(company_create_params)
if #company.save
render json: { success: true }
else
render status: 500, json: {
error: true,
reason: #company.errors.full_messages.to_sentence
}
end
end

Rails best_in_place Unprocessable Entity

I'm trying to edit the name field of a model with the best_in_place gem to edit items directly in line. When trying to do so I'm getting a an error 422 Unprocessable Entity.
I've done some research and found out in the response the controller is expecting not only the name attribute but also the group and some other attributes.
["Group must exist","Lumo can't be blank","Lumo is not a number"]
I have setup my controller in the correct way (I think).
materials_controller.rb
def update
#material = Material.find(params[:id])
if params[:commit] == "Save" then
success = #material.update(material_params)
params[:create_pure_composition] = false
else
#material = Material.new(material_params)
#material.user_id = current_user.id
success = #material.save
end
respond_to do |format|
if success
plot1 = prepare_e_plot(#material)
plot2 = prepare_st_plot(#material)
format.html { redirect_to #material }
format.json { render json: { plot1: plot1, plot2: plot2, status: 200 } }
else
format.html { render 'edit' }
format.json { respond_with_bip(#material) }
end
end
end
Is there a way with best_in_place to send these value's when updating the name attribute? I've tried with the params attribute from best_in_place.
<%= best_in_place #material, :name, as: :input, params: { group_id: #material.group_id } %>
This wasn't sending any extra params with the update.
Here's is what the Material model looks at.
material.rb
class Material < ActiveRecord::Base
belongs_to :user
belongs_to :group
validates :name, presence: true, uniqueness: {scope: :user_id}
validates :lumo, presence: true, numericality: true
end
Does anybody know why it's asking for other attributes and why best_in_place is not sending those along?
I figured out what the problem was and how to fix it. We use an option to Save or Save As when editing materials. In the controller we therefore check for the params[:commit].
By editing the url I was able to send in the params[:commit] with the update with best_in_place. Here is how the best_in_place code ended up like:
<%= best_in_place #material, :name, as: :input, url: material_path(#material, commit: "Save") %>

Rails method executing, when it should not?

rails 3.2
In my tickets_controller, I have the following:
def update
#ticket = Ticket.find params[:id]
authorize! :update, #ticket
#ticket.assign_attributes(params[:ticket])
#ticket.customer_info.company = #ticket.customer if #ticket.customer_info
#ticket.admin_context = true
if !params[:ticket_update_type].nil? && params[:ticket_update_type] == 'save_lead_billing'
#ticket.process_lead_billing params
end
if #ticket.save
#ticket.update_attribute(:ticket_type, #ticket.ticket_profile.ticket_type)
redirect_to [:admin, #ticket], notice: success_message
else
#ticket.customer_info_type = 'existing'
#can_update_ticket = can? :update, #ticket
#tag_groups = TagGroup.with_type('ticket').for_company(#ticket.customer_id)
flash.now[:error] = #ticket.errors.full_messages.join(', ')
render action: "show"
end
end
In my ticket.rb model, I have the following:
def process_lead_billing params
if params[:lead_billing]["pre_tax_total"].nil? || params[:lead_billing]["post_tax_total"].nil?
return
end
# handles case where billing infor has not been added to lead ticket
if params[:ticket_update_type] == "save_lead_billing"
lead_billing = LeadBilling.new(
:ticket_id => self.id,
:pre_tax_total => params[:lead_billing]["pre_tax_total"],
:post_tax_total => params[:lead_billing]["post_tax_total"],
:status => 'entered'
)
lead_billing.save!
end
end
And in lead_billing.rb model, I have the following:
class LeadBilling < ActiveRecord::Base
validates_presence_of :pre_tax_total, :post_tax_total
validates_numericality_of :pre_tax_total, greater_than: 0, allow_blank: false, only_integer: false
validates_numericality_of :post_tax_total, greater_than_or_equal_to: :pre_tax_total, allow_blank: false, only_integer: false
The problem, is that when the form is submitted, with the pre_tax_total and post_tax_total empty, I am getting an error message.
From the log file:
Started PUT "/admin/tickets/163812" for 73.83.66.151 at 2016-12-21 22:05:28 +0000
Processing by Admin::TicketsController#update as HTML
and the params are:
[utf8] => ✓
[authenticity_token] => mNt+aI3YInoutup4UsBGZ8zZkeFRYCBZAsxEv4JPvoE=
[ticket] => Array
(
......
)
[time_span] =>
[city] => Draper
[state] => Utah
[admin] => true
[specialty] =>
[services] =>
[inventories] =>
[ticket_update_type] => save_lead_billing
[ticket_id] => 1480720184_0388234_ticket
[lead_billing] => Array
(
[pre_tax_total] =>
[post_tax_total] =>
)
[id] => 163812
From the log file, the error is:
Validation failed: Pre tax total can't be blank, Pre tax total is not
a number, Post tax total can't be blank, Post tax total is not a number from
And then it points me to the line in the tickets_controller.rb, where the processing_lead_billing method is called (correctly), and then to the line in the processing_lead_billing method, where it tries to save the lead billing.
Execution should have halted, when I checked for nil, but it continued to execute. Any ideas?
Rails has a blank? method that is usually preferred when testing form params.
nil? is a ruby method that will only return true if the object is nil, while blank? covers all sorts of use cases (empty string, empty array, empty dictionary and of course nil value).
In your case, the returned value are most likely empty string given how rails work, and so you should test for blank? instead of nil?.

How to handle strong parameters as a array in Nested Form? Rails 4

The context is as follows, I have entities that can have multiple roles. These roles are manageable by the user.
For example, Entity named "Lipsum" may be "Cashier and Salesperson". So, this is a relation many_to_many.
So I have my 3 models: Entity, type_entity and entity_by_type
class Entity < ActiveRecord::Base
has_many :entity_by_types
has_many :type_entities, :through => :entity_by_types
accepts_nested_attributes_for :entity_by_types
end
class EntityByType < ActiveRecord::Base
belongs_to :entity
belongs_to :type_entity
end
class TypeEntity < ActiveRecord::Base
has_many :entity_by_types
has_many :entities, :through => :entity_by_types
end
I have an ordinary CRUD for entity types.
Now, in the CRUD of entities, I have a field Select-Option Multiple. In which the user chooses has 1 or more types, the entity that is creating.
Then my Controller Entity is as follows:
class Logistics::EntitiesController < ApplicationController
def index
#type_entities = TypeEntity.all
render layout: false
# I use this for show All entities by TypeEntity in my view index
end
def show
end
def new
#type_entities = TypeEntity.all
#entity = Entity.new
render layout: false
end
def create
entity = Entity.new(entity_parameters)
if entity.save
flash[:notice] = "Succesfull!."
redirect_to :action => :index
else
flash[:error] = "Error."
redirect_to :action => :index
end
end
def edit
#entity = Entity.find(params[:id])
#type_entities = TypeEntity.all
#action = 'edit'
render layout: false
end
def update
entity = Entity.find(params[:id])
entity.update_attributes(entity_parameters)
flash[:notice] = "Succesfull."
redirect_to :action => :index
end
def destroy
#entity = Entity.destroy(params[:id])
render :json => #entity
end
private
def entity_parameters
params.require(:entity).permit(:name, :surname, entity_by_types_attributes: [:id, :entity_id, :type_entity_id])
end
end
And my partial form (for method create and Update) is:
= simple_form_for([:namespace, #entity], html: {class: 'form-horizontal' }) do |f|
= f.input :name, placeholder: "Nombre", input_html: { class: 'form-control' }, label: false
= f.input :surname, placeholder: "Apellidos", input_html: { class: 'form-control' }, label: false
%select.select2#type-entity-select{:name => "entity[entity_by_types_attributes][type_entity_id][]", :style => "width:100%;padding: 0;border: none;", :multiple => true}
- #type_entities.each do |tent|
%option{value: "#{tent.id}"}
= tent.name
But, when I click in button submit, and "type_entity_id" have 1 or more values; in my database only display a 1 record where, entity_id is OK, however type_entity_id is NULL.
Moreover only view a 1 record, when should see 1 or more records, depending on the number of types of choice in the form.
The problem here is the way of pass type_entity_id in form of array. So, How I can do that?
P.D
The following is how the params go to my controller:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ASD"1231+Dssr6mRJcXKh9xHDvuVDmVl4jnwIilRBsuE=", "entity"=>{"name"=>"Lorem", "surname"=>"Ipsum", "entity_by_types_attributes"=>{"type_entity_id"=>["1", "4"]}}}
Try this:
def entity_parameters
params.require(:entity).permit(:name, :surname, entity_by_types_attributes: [:id, :entity_id, {:type_entity_id => []}])
end
Edit:
In your form and in def entity_parameters replace type_entity_id with type_entity_ids
Thus, the parameter will refer to a set (array) not to a single object. These are the generic method syntaxes:
Model.associate_id = some integer
Model.associate_ids = an array (for a has_many relation)

how do I check student_id before input student class record?

My thought of this programming content as below: 'adult' symbolize the student data table and 'adultclasses' symbolize course selection data table.
When the data keyin person input the student data,they have to avoid input the student_id which not existing in adult content. However, I’ve try several times still fail.
def create
#adult_class = AdultClasse.new(params[:adult_classe])
#adults_session_descriptions = AdultsSessionDescription.all
if
#adult_class = #adult_class.find(:student_id) == Adult.find_by_student_id(:student_id)
flash[:notice] = "no this student id record!"
redirect_to:action => :index
else
respond_to do |format|
if #adult_class.save
format.html { redirect_to(#adult_class, :notice => 'adult classe was successfully created.') }
format.xml { render :xml => #adult_class, :status => :created, :location => #adult_class }
else
format.html { render :action => "new" }
format.xml { render :xml => #adult_class.errors, :status => :unprocessable_entity }
end
end
end
Because I was mistaken use plural names to build the program, I’ve made up in adultclasse.rb as below:
# encoding: utf-8
class AdultClasse < ActiveRecord::Base
set_table_name "adult_classes"
belongs_to :adult
#has_many :adults_classe_ship
#has_many :adult, :through => :adults_classe_ship
validates :student_id, :presence => {:message => "please input student id"},
:length => {:message => "too short or too long", :minimum => 4, :maximum => 12}
end
this is model Adult.rb
# encoding: utf-8
class Aadult < ActiveRecord::Base
before_save :fix_cname
def age
now = Time.now.utc.to_date
dob = self.birthday
now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
end
private
def fix_cname
self.cname = self.cname.gsub(/[\w\s\b\$[:punct:]]/ , '')
end
#has_many :adults_classe_ship, :dependent => :destroy
#has_many :adult_classe, :through => :adults_classe_ship

Resources