How to retrieve sixth record from database in rails using Where query - ruby-on-rails

I want to retrieve sixth, seventh and eighth record from database using ruby on rails, but it's possible only till fifth, after that undefined method sixth is coming. Please suggest me if there is any possible way.
Following is my code which I tried:
#reporting_masters_travel_requests4 = ReportingMastersTravelRequest.where(travel_request_id: #travel_request.id,status: nil).fifth

if #reporting_masters_travel_requests2 = ReportingMastersTravelRequest.where(travel_request_id: #travel_request.id,status: nil)[1]
ReportingMastersTravelRequest.where(reporting_master_id: #reporting_masters_travel_requests2.reporting_master_id).update_all(status: "true",daily_bill_comment: #comment)
TravelRequest.where(id: #travel_request.id).update_all(reporting_master_id: #reporting_masters_travel_requests3.reporting_master_id)
flash[:notice] = 'Daily Bill Request Send To Higher Authority For Approval'
elsif #reporting_masters_travel_requests3 = ReportingMastersTravelRequest.where(travel_request_id: #travel_request.id,status: nil)[2]
ReportingMastersTravelRequest.where(reporting_master_id: #reporting_masters_travel_requests3.reporting_master_id).update_all(status: "true",daily_bill_comment: #comment)
TravelRequest.where(id: #travel_request.id).update_all(reporting_master_id: #reporting_masters_travel_requests4.reporting_master_id)
flash[:notice] = 'Daily Bill Request Send To Higher Authority For Approval'
elsif #reporting_masters_travel_requests4 = ReportingMastersTravelRequest.where(travel_request_id: #travel_request.id,status: nil)[3]
ReportingMastersTravelRequest.where(reporting_master_id: #reporting_masters_travel_requests4.reporting_master_id).update_all(status: "true",daily_bill_comment: #comment)
TravelRequest.where(id: #travel_request.id).update_all(reporting_master_id: #reporting_masters_travel_requests5.reporting_master_id)
flash[:notice] = 'Daily Bill Request Send To Higher Authority For Approval'
else
flash[:alert] = 'No Reporting Manager is present'
end
I have used the above code and it works perfectly,but its not so dynamic as i manually need to specify for how many time if want to check in table via array [4].But problem is what if 10 records are present in database then for this the above logic will fail.

You are using where to get records from database and it returns array of objects so you can use something like this:
#reporting_masters_travel_requests4 = ReportingMastersTravelRequest.where(travel_request_id: #travel_request.id,status: nil)[5]

You can do as follows:
#reporting_masters_travel_requests = ReportingMastersTravelRequest.where(travel_request_id: #travel_request.id,status: nil)
#reporting_masters_travel_requests.each do |record|
#Something like record.update record.save
end
#set a msg like no more records after loop
msg="No more records"

Related

How to filter out inactive emails from an array of emails in a rails application?

I am currently working on a ticket where it asks me to filter out any inactive email to be sent to the recipient. Here is the method I am working on:
def self.delivering_email(message)
return if email_to_be_delivered?(message.subject)
email_list = message.to
if email_list.is_a?(String)
email_list = email_list.split(",").map(&:strip)
end
email_list.each { |email|
identity = Identity.find_by(email: email)
next if identity.nil?
# email_list.delete(email) unless identity.try(:preferred_user).active?
email_list.select(email) if identity.try(:preferred_user).active?
}
message.to = email_list
message.perform_deliveries = !email_list.empty?
end
the "# email_list.delete(email) unless identity.try(:preferred_user).active?" I commented out because the QA mentioned that ONLY one inactive email filters out and does not fully filter other inactive emails in the array. I assumed instead of .delete I have to use .select but don't know if it works because I don't have any way to test and reproduce the error on my end, or how to implement it the right way.
Any help will be appreciated.
You're trying to modify an array while you're iterating over it, that may lead to weird behavior. One option is to just use a separate array.
Since you are already iterating with email_list.each you can call next if the current email does not satisfy you, like you already do for identity.nil?.
So it may look smth like
valid_emails = []
email_list.each { |email|
identity = Identity.find_by(email: email)
next if identity.nil? || !identity.try(:preferred_user).active?
valid_emails << email
end
message.to = valid_emails

How find the distance between two objects?

Im using geocode. The idea is our partners can post products with an address. When they do so it fetches the latitude and longitude. Now when our customers go to buy that product they have to enter in a delivery address to tell us where to deliver the product. However if they delivery address is not within 20 miles of the product they are not allowed to get the product delivered.
Im getting an error message saying this "undefined method `latitude' for nil:NilClass"
Like I said the product.longitude, product.latitude is already set when the users are trying to order.
Not sure if it's because the order.delivery_address(lat, long) is not submitted into the database yet and its trying to check the distance. Here my code below
So My question is how can is how can i find the distance between the product address and order address and I want to show a alert message to the user if the distance between the two is over 20 miles.
def create
product = Product.find(params[:product_id])
if current_user == product.user
flash[:alert] = "You cannot purchase your own property"
elsif current_user.stripe_id.blank? || current_user.phone_number.blank?
flash[:alert] = " Please update your payment method and verify phone number please"
return redirect_to payment_method_path
elsif Geocoder::Calculations.distance_between([product.latitude, product.longitude], [#order.latitude, #order.longitude]) < 20
flash[:alert] = "The delivery address you provided is outside the delivery zone. Please choose a different product."
else
quantity = order_params[:quantity].to_i
#order = current_user.orders.build(order_params)
#order.product = product
#order.price = product.price
#order.total = product.price * quantity + product.delivery_price
# #order.save
if #order.Waiting!
if product.Request?
flash[:notice] = "Request sent successfully... Sit back and relax while our licensed dispensary fulfil your order :)"
else
#order.Approved!
flash[:notice] = "Your order is being filled and it will delivered shortly:)"
end
else
flash[:alert] = "Our licensed dispensary cannot fulfil your order at this time :( "
end
end
redirect_to product
end
You set #order in the following line:
#order = current_user.orders.build(order_params)
But you try to call its longitude and latitude methods above this, before you even set #order variable. To simply fix this problem, you can move this line up, it can even be located at the beginning of create method, since it doesn't depend on product or anything like that:
def create
#order = current_user.orders.build(order_params)
# ...
end
Although, there are number of problems in your code, like method names starting with capital letters (you can do it, but you shouldn't, it's against the convention) or overall complexity of the method.
You should move the business logic to the model where it belongs.
So lets start by creating a validation for the product distance:
class Order < ApplicationRecord
validates :product_is_within_range,
if: -> { product.present? } # prevents nil errors
# our custom validation method
def product_is_within_range
errors.add(:base, "The delivery address you provided is outside the delivery zone. Please choose a different product.") if product_distance < 20
end
def product_distance
Geocoder::Calculations.distance_between(product.coordinates, self.coordinates)
end
end
Then move the calculation of the total into the model:
class Order < ApplicationRecord
before_validation :calculate_total!, if: ->{ product && total.nil? }
def calculate_total!
self.total = product.price * self.quantity + product.delivery_price
end
end
But then you still have to deal with the fact that the controller is very broken. For example:
if current_user == product.user
flash[:alert] = "You cannot purchase your own property"
Should cause the method to bail. You´re not actually saving the record either. I would start over. Write failing tests for the different possible conditions (invalid parameters, valid parameters, user is owner etc) then write your controller code. Make sure you test each and every code branch.

Take random ids, then store those random ids into the db

so I'm working on a code snippet that essentially takes out 35 random ids from the table List.
What I would like to do to find the ids that got randomly generated, store them into a database called Status.
The purpose is to avoid duplication the next time I get a new 35 random ids from the List. So I never get the same random id twice.
Here's what I've tried, but been unsuccessful to get working.
#schedule = current_user.schedules.new
if #schedule.save
#user = User.find(params[:id])
Resque.enqueue(ScheduleTweets, #user.token)
#schedule.update_attribute(:trial, true)
flash[:notice] = "success"
redirect_to :back
else
flash[:alert] = "Try again."
redirect_to :back
end
and the worker:
def self.perform(user_token)
list = List.first(6)
#status = list.statuses.create
list.each do |list|
Status.create(list_id: "#{list}")
if list.avatar.present?
client.create_update(body: {text: "#{list.text}", profile_ids: profile_ids, media: { 'thumbnail' => 'http://png-1.findicons.com/files/icons/85/kids/128/thumbnail.png', 'photo' => 'http://png-1.findicons.com/files/icons/85/kids/128/thumbnail.png' } })
end
end
end
however the Status.create(list_id: #list) doesn't work.
Does anybody have any idea what is going on, and how I can make the list_ids get saved successfully to Status?
It's also associated:
list has many statuses, and status belongs to list
The following line of code is wrong:
Status.create(list_id: "#{list}") # WRONG
In your case the list variable is a List instance. And you're passing its string version to list_id which expects an integer.
Do this:
Status.create(list_id: list.id)
Or this:
list.statuses.create
I think the following will also work:
Status.create(list: list)

Rails Parse CSV with empty cells and correctly handle exceptions

I am trying to allow users to upload csv files, however I am having some issues trying to figure out how to handle errors from the file itself.
My controller method:
def create
Product.import_csv(file)
redirect_to products_path, :flash => { :notice => "Items Added!" }
end
My model method to import the file:
def self.import_csv(file)
csv = CSV.read(file.path), :headers => true)
csv.each do |row|
item_id = row[0]
start_date = Date.parse(row[1])
order_date = Date.parse(row[2])
new_rec = where(item_id:item_id, order_date:order_date).first_or_initialize
new_rec.save!
end
end
All this works well when the file is properly formatted, however Im confused as to how to handle exceptions. Once such exception is when start_date or order_date are missing; I get an no implicit conversion of nil into String because I'm attempting to parse the date of an empty cell. Even though I have validations in my model for presence, they only get fired on the save action.
I don't want to silently ignore these errors with a rescue block, but instead redirect back, and notify the user.
How can I handle such exceptions, so that the jobs fails, and the user gets notified of the error, not specifically solely the error given above, but including errors we can't account for? Another example would be a empty line or something we cant even account for. How can I handle such errors, and notify the user with, for example, a generic "Bad data" message?
Should I handle this in my model or my controller?
If you have presence validations for the dates, you can simply assign them only if they exist, and let your model do the rest:
def self.import_csv(file)
csv = CSV.read(file.path), :headers => true)
csv.each do |row|
item_id = row[0]
start_date = row[1].nil? ? nil : Date.parse(row[1])
order_date = row[2].nil? ? nil : Date.parse(row[2])
new_rec = where(item_id:item_id, order_date:order_date).first_or_initialize
new_rec.save!
end
end

wrong content loaded due to browser cache

I used Ruby on Rails for my website. In one web page, it will load a poll information based on the poll id, which set in url like "http://mywebsite/polls/1". The poll information includes the poll owner name, the poll title, the item pictures in the poll and the people's name who voted on the poll.
I found sometimes it loaded wrong information. That is, it loaded the wrong poll owner name, poll title and voted people from the other poll while the item pictures are correct.I checked the back end and found there was nothing wrong in rails controller. All the variables got the right values. But the chrome browser told me the view is wrong.
If I cleared all the cache and reload the page then it would work normally.Anyone knows why does it happen and what should I do? Thanks
The relavant action codes:
def show
#poll=Poll.where("is_deleted = false AND id = #{params[:id]}")[0]
#items=#poll.items.where("is_deleted = false")
#voted_user_ids = #poll.audiences.where('has_voted != 0').map(&:user_id).uniq
#voted_users = User.where('id IN (?)',#voted_user_ids)
#voted_user_names = #voted_users.map(&:user_name)
if current_user.nil?
#poll_vote_url = "/voted_choice"
else
#current_user_name = current_user.user_name
#poll_vote_url = "/audiences/"+#poll.id.to_s
#if_current_user_voted = #voted_users.include?(current_user)
#is_poll_owner = (current_user == #poll.user)
check_item_id_in_cookies
end
end
def check_item_id_in_cookies
if !cookies.signed[:item_id].nil?
item = Item.find(cookies.signed[:item_id].to_i)
#create audience if the voter is not the poll owner
if current_user == item.poll.user
flash.now[:alert] = "You can't vote on your own poll."
cookies.signed[:item_id] = nil
else
create_audience cookies.signed[:item_id]
end
end
end
def create_audience item_id
#item_id = item_id.to_i
#item = Item.find(#item_id)
#poll = #item.poll
#voted_user_ids = #poll.audiences.where('has_voted != 0').map(&:user_id).uniq
if #voted_user_ids.include?(current_user.id)
flash.now[:alert]="You already voted."
else
audience = #item.poll.audiences.find{|audience| audience.user_id == current_user.id} || Audience.create(:poll_id => #poll.id,:user_id => current_user.id)
#update audience
audience.is_following = true
audience.has_voted = #item.id
audience.save
cookies.signed[:item_id]=nil
flash[:alert]="Thank you for your vote"
redirect_to "/polls/#{#poll.id}"
end
end
Please monitor the network while loading and reloading the page. Especially to request to request to http://mywebsite/polls/1. Check the response headers as well. Even if you don't do on application side the web server or a proxy server may be modifying the request.
You can find help on who to use the network panel of chrome here.

Resources