Validation for datetime - ruby-on-rails

I have problem with validation in my project. I need to validate datetime when saving reservation.
It showing message "This date is reserved." but always create new reservation :(
It can be 3 identical datetime values and not more. Where I have problem in my code?
(I am learning RoR, so, please, be patient. :)
def create
#reservation = Reservation.create!(reservation_params)
#check_count = Reservation.select(:date).where('date = ?', #reservation.date).count
if #check_count <= 3
if #reservation.save!
ReservationMailer.new_service(#reservation).deliver
flash[:success] = "Successfully created reservation."
redirect_to root_path
else
render 'new'
end
else
flash[:error] = "This date is reserved."
render 'new'
end
end

when you do
#reservation = Reservation.create!(reservation_params)
it will create the object and save it before your condition is checked. you should do
#reservation = Reservation.new(reservation_params)
this way it will only initialise it and not save unless your condition is met ie #check_count <= 3
and then when you do .save on it. it will be saved.

Related

How to display model error messages within notice in ruby

I did a date validation in model which should display a message on page, but for some reason it isn't. I need this message to be shown in notice on error. Currently I just see the message in controller (Order not registered) but I need to see the reason (Delivery date should be from now). How can I do that?
model
def delivery_date_from_now_only
if self.delivery_date.present? && self.delivery_date <= Date.today
self.errors.add(:delivery_date, messsage: 'Delivery date should be from now')
end
end
controller
def create
#order = Order.new(order_params)
#order.user = current_user
if #order.save
flash[:notice] = 'Order registered successfully'
return redirect_to #order
end
#warehouses = Warehouse.all.order(:name)
#suppliers = Supplier.all.order(:brand_name)
#users = User.all.order(:name)
flash.now[:alert] = 'Order not registered'
render :new, status: 422
end
if you call #order.valid? it will validate your model an also populate errors for that object. that means #order.errors.messages will be a hash with { :delivery_date => ["Delivery date should be from now"]} etc (other errors will be in there as well) which u can use to do some flashes.

RAILS: Popup/warning/message before_create

I want to show a popup/message saying update some other table also based on a particular field while creating a record.
Is there a way to do it using validations or action links?
I want to do something like below:
validates :fieldc, if: :should_update?, message: "Update fielda and fieldb in tablex also"
bef should_update?
fieldc == "req_value"
end
I am sure the above validation won't work. But I want to show the popup if fieldc == req_value and the record should be created. Is there a way to do it?
Thanks.
EDIT:
can I do it the following way?
after_create :update_tablex
def update_tablex
if self.should_update?
flash[:notice] = 'Please update fielda and fieldb in tablex also'
else
flash[:notice] = 'Record updated successfully.'
end
end
def should_update?
fieldc == "req_value"
end
But Iam still getting the NameError (undefined local variable or method 'flash' for #)
This is really a controller issue, and should be addressed in the controller, not the model. The model is never responsible for controlling the logic of what's viewed and how the workflow progresses. Best bet would be to set a flash message that shows what they need to do, and as a convenience redirect them to the tablex edit view.
in your create method...
def create
...
if #record.save
if #record.should_update?
flash[:notice] = 'Please update fielda and fieldb in tablex also'
redirect_to edit_tablex_path(#record.tablex)
else
flash[:notice] = 'Record updated successfully.'
redirect_to #record
end
else
render :new
end
end

Custom updated_at for a specific field/attribute in rails

I currently have a method that increments an attribute on the Subscriber. It's visit attribute that takes in a int. My question is - Can I find that Subscriber that last had their visit attribute updated? In the console it would look something like this - Subscriber.find("visit +=1").last <- completely wrong BTW, but I assume it would look kinda like that? Does anybody know how I can call this in the console?? Any help would be great.
Controller Method:
def visit
#subscriber = Subscriber.find_by(params[:phone_number])
if #subscriber
#subscriber.visit ||= 0
#subscriber.visit += 1
#subscriber.save
flash[:notice] = flash[:notice] = "Thank You #{#subscriber.first_name}. You have #{#subscriber.days_till_expired} until renewal"
redirect_to subscribers_search_path(:subscriber)
else
render "search"
end
end
As you can see I would like to call the Subscriber who last used this method to update the visit attribute on their object. Let me know if you need more info.
You can always get the last updated item like this:
Subscriber.order('updated_at desc').first
But :updated_at will update even if anything other than :visit is updated. So you have to write a little migration to add a custom field which will do the work for us.
rails g migration AddLastVistedToSubscriber last_visited:datetime
Run rake db:migrate to add :last_visited to our table. Now we need to update that field whenever we're doing +1 to :visit.
def visit
#subscriber = Subscriber.find_by(params[:phone_number])
if #subscriber
#subscriber.visit ||= 0
#subscriber.visit += 1
if #subscriber.save
#subscriber.touch(:last_visited) #this will update the last_visited with the update time
flash[:notice] = flash[:notice] = "Thank You #{#subscriber.first_name}. You have #{#subscriber.days_till_expired} until renewal"
redirect_to subscribers_search_path(:subscriber)
end
else
render "search"
end
end
Now we can search easily which subscriber's :visit was incremented last.
Subscriber.order('last_visited desc').first

Value for Active Record attribute not getting saved properly

In the code below, I am trying to set the popup variable for the Company object, but where it currently is located, it is not getting set when the user hits the submit button on the page where a company object is created.
When I put the line in question before the if statement, the popup variable gets set, but because the object hasn't been saved yet, the #company.id has been set yet, so that part of the popup string I am trying to create isn't set properly.
Any ideas how to get my popup variable to be set properly?
def create
#company = Company.new(company_params)
if #company.save
redirect_to map_path
flash[:success] = "Company Successfully Added"
#company.popup = "<h3><a href='companies/#{#company.id}'>#{#company.name}</a></h3>"
else
render 'new'
end
end
If popup is a company attribute and if you need to save it, just use 'before_save':
def create
#company = Company.new(company_params)
if #company.save
redirect_to map_path
flash[:success] = "Company Successfully Added"
else
render 'new'
end
end
Model:
before_save :set_popup_value
private
def set_popup_value
popup = "<h3><a href='companies/#{self.id}'>#{self.name}</a></h3>"
#self.update_attributes(:popup => popup)
self.update_column(:popup => popup)
end
else, if you want 'popup' just to display it and not to save in a database, then you must use attr_accessor.
Model:
class Company < ActiveRecord::Base
attr_accessor :popup
end
Controller:
def create
#company = Company.new(company_params)
if #company.save
#company.popup = "<h3><a href='companies/#{#company.id}'>#{#company.name}</a></h3>"
redirect_to map_path
flash[:success] = "Company Successfully Added"
else
render 'new'
end
end
Hope it helps :)

Validation errors appearing before submitting information in Rails?

I have two models, Character and Initiative, and their relationship is Character has_one Initiative and Initiative belogns_to Character. I'm working on validation for Initiative, and I have it working, but the issue is all of my validation errors appear when creating a new Initiative record for a Character, before entering any information. Any ideas? Here's my code from Initiatives controller:
def new
#character = Character.find(params[:character_id])
#initiative = #character.create_initiative(params[:initiative])
end
def edit
#character = Character.find(params[:character_id])
#initiative = #character.initiative
end
def create
#character = Character.find(params[:character_id])
#initiative = #character.create_initiative(params[:initiative])
if #initiative.save
redirect_to character_path(#character), :notice => "initiative successfully created!"
else
render :action => "new"
end
end
def update
#character = Character.find(params[:character_id])
#initiative = #character.initiative
if #initiative.update_attributes(params[:initiative])
redirect_to character_path(#character), :notice => 'Initiative information was successfully updated.'
else
render :action => "edit"
end
end
And here's the validation itself from my model:
validates_presence_of :dex, :misc, :speed
validates_numericality_of :dex, :misc, :speed
I'm pretty sure the problem lies in the create or new methods, but I'm not sure why it's triggering the validation before a user enters any information. Any help? Maybe not a huge concern, since the code IS working, but I'd rather not display an error message before actually getting an error. Thanks!
shouldn't you be using build_initiative instead of create_initiative in your new action ? no need to save an object when sending to the user a form that intends to create it. Moreover, if your character has_one initiative, he can only have one so i doubt AR appreciates that you try to create another.
see http://guides.rubyonrails.org/association_basics.html#has_one-association-reference

Resources