Rake task to update records - ruby-on-rails
I am doing a rake task that is scrapping a website in order to find concerts:
lib/tasks/my_task.rake
task :find_concerts => :environment do
doc = Nokogiri::HTML(open(url))
data = doc.search('#dateconcert table')
data = data.css('.jaunec' ).map { |tr| tr.css('td').map(&:text) } + doc.css('.jaunef' ).map { |tr| tr.css('td').map(&:text) }
data.each do |concert|
c = Concert.new
c.date = concert[0]
c.city = concert[1]
c.save
end
end
What I want
I want to get an alert when a new concert is added ( on the website I am scrapping), so the tasks will be run everyday.
My problem
I want my Concerts list to be updated if there is a new record...
With the task I wrote it finds again the records that are already stored and duplicated them...
I only want the new records that could be found...
In the end I would like to compare what is new between the two last tasks in order to send an alert if something new was found.
EDIT
This is what data returns
[
["03 Décembre 2017", "PONT L\u0092ABBE (29) | Centre Culturel Le Triskell "],
["26 Janvier 2018", "MONTPELLIER (34) | Le Jam "],
["17 Février 2018", "BLOIS (41) | All That Jazz / Les Lobis "],
["22 Mars 2018", "MOISSAC (82) | Hall de Paris "],
["24 Mars 2018", "LAX (Baraqueville) (12) | Festival Lax'N Blues LAX\u0092N "],
["08 Décembre 2017", "ECHANGE CULTUREL CAMEROUN (0) | au 18 décembre 2017 - Organisation tournée MFR "],
["27 Janvier 2018", "LE THOR (84) | Le Sonograf "],
["16 Mars 2018", "CHAUMONT (52) | Le Nouveau Relax "],
["23 Mars 2018", "AUCH (32) | Le Cri'Art "]
]
I found a solution that may need some refactoring, though.
So I created two tasks,
find_concerts that will be run manually for the first scrap
update_concerts that will be run every day
task
require "nokogiri"
require "open-uri"
require "date"
require "time"
namespace :scrap do
desc "This get MM concerts"
url = "http://mountain-men.fr/concerts/"
doc = Nokogiri::HTML(open(url))
data = doc.search('#dateconcert table')
data = data.css('.jaunec' ).map { |tr| tr.css('td').map(&:text) } + doc.css('.jaunef' ).map { |tr| tr.css('td').map(&:text) }
task :find_concerts => :environment do
data.each do |concert|
c = Concert.create
c.date = concert[0]
c.city = concert[1]
c.save
end
end
task :update_concerts => :environment do
existing_date = Concert.all.map { |c| [c.date, c.city] }
data.each do |concert|
c = Concert.create
c.date = concert[0]
c.city = concert[1]
c.save unless existing_date.include?([concert[0], concert[1]])
end
Concert.where(city: nil, date: nil).destroy_all
end
end
I am not sure if I understand you correctly, but what you need to do is to check if it exists and other wise create.
I would do some thing like this.
task :find_concerts => :environment do
doc = Nokogiri::HTML(open(url))
data = doc.search('#dateconcert table')
data = data.css('.jaunec' ).map { |tr| tr.css('td').map(&:text) } + doc.css('.jaunef' ).map { |tr| tr.css('td').map(&:text) }
data.each do |concert|
Concert.where(data: concert[0], city: concert[1]).first_or_create
end
end
Now you only create if it doesn't exist. Then when you create one you can set a hook.
class Concern
after_create :send_notification
def send_notification
# send email here
end
end
Related
Ruby Seed - How to store subcategories for each sneaker and remove duplicates?
I want to create my database from CSV data. For that I have parse my file and I start to seed. In my .csv file, there are sneakers name with subcategories like in the picture : In my db/seeds.rb, i coded this : # db/seeds.rb csv_text = File.read(Rails.root.join('lib', 'seeds', 'air_jordan.csv')) csv = CSV.parse(csv_text, :headers => true, :encoding => 'ISO-8859-1') air_jordan_subcategories = ['1', '11', "Jordan OFF-WHITE", "Future", "Women", "High"] csv.each do |row| s = Sneaker.new s.name = row['Name'] air_jordan_subcategories.each do |sub| if row['Subcategory'] == sub s.subcategory << sub end end s.save end What I want is that the pair “Jordan 1 Mid Banned (2020)“, appears like this in my database: => #<Sneaker:0x00007ffdbd4a5980 id: 1, name: "Jordan 1 Mid Banned (2020)", subcategory : ["Mid", "1"]> While for the moment, in my database I have 2 times the same pair because I have 2 different subcategories : => #<Sneaker:0x00007ffdbd4a5980 id : 1, name : "Jordan 1 Mid Banned (2020)", subcategory : ["Mid"]> => #<Sneaker:0x00007ffdbd4a5933 id: 2, name : "Jordan 1 Mid Banned (2020)", subcategory : ["1"] > I can’t find a logical solution for this, what I would like is simply : air_jordan_subcategories.each do |sub| while row['category'] == sub s.subcategory << sub row += 1 end end But row += 1 doesn’t work, and while row['category'] == sub trigger an infinite loop. Thanks for helping !
Can't loop through JSON data because of the error "no implicit conversion of hash into integer"
Hello and good afternoon all! I am getting an error in my console that states "TypeError: No implicit conversion of hash into integer" and I know that it is referring to my loop in my Ruby class document. Here is my Ruby file: require 'HTTParty' require 'pp' require 'pry' =begin find a way to access the latitude and longitude of the nearest charging station globally find a way to access the latitude and longitude of the user create a function that finds the nearest station based on accepting both sets of coordinates and finds the difference =end class ChargingStations include HTTParty attr_accessor :pois puts "loading" ##latitude = '' base_uri 'https://api.openchargemap.io/v2' def self.puts_latitude puts ##latitude end def initialize(pois) ##pois = pois ##latitude = ##pois puts ##pois end def self.put_value puts ##latitude end def self.find_sites for i in ##pois do puts ##pois[i] if ##pois[i]["AddressInfo"]["StateOrProvince"] == "New York" puts ##pois[i] end end end def self.generate response = get('/poi') puts "got here" if response.success? puts "success" self.new(response) else puts "failure" raise response.response end end end binding.pry If you are able to answer the question, please explain why my loop does not work for myself and future developers. Thank you!
Why don't you give this a try: class ChargingStations include HTTParty ##latitude = '' base_uri 'https://api.openchargemap.io/v2' class << self def pois ##pois end def puts_latitude puts ##latitude end def put_value puts ##latitude end def state_or_provinces #state_or_provinces ||= ##pois.map do |poi| poi.try(:[],'AddressInfo').try(:[],'StateOrProvince') end.uniq end def find_sites(state_or_province=nil) #state_or_province = state_or_province #state_or_province ||= 'New York' ##pois.select do |poi| poi.try(:[],'AddressInfo').try(:[],'StateOrProvince') == #state_or_province end end def generate response = get('/poi') if response.success? ##pois = response.parsed_response ##latitude = ##pois return true else puts "failure" raise response.response end end end # Class methods end Then, in console, I get: ChargingStations.generate => true ChargingStations.find_sites.count => 2 ChargingStations.find_sites.first => {"ID"=>112491, "UUID"=>"5EA5B030-AFEF-4CFA-88DF-3A9F6CFFDAB5", "ParentChargePointID"=>nil, "DataProviderID"=>1, "DataProvider"=>{"WebsiteURL"=>"http://openchargemap.org", "Comments"=>nil, "DataProviderStatusType"=>{"IsProviderEnabled"=>true, "ID"=>1, "Title"=>"Manual Data Entry"}, "IsRestrictedEdit"=>false, "IsOpenDataLicensed"=>true, "IsApprovedImport"=>true, "License"=>"Licensed under Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)", "DateLastImported"=>nil, "ID"=>1, "Title"=>"Open Charge Map Contributors"}, "DataProvidersReference"=>nil, "OperatorID"=>5, "OperatorInfo"=>{"WebsiteURL"=>"http://www.chargepoint.net/", "Comments"=>nil, "PhonePrimaryContact"=>"1-888-758-4389", "PhoneSecondaryContact"=>nil, "IsPrivateIndividual"=>false, "AddressInfo"=>nil, "BookingURL"=>nil, "ContactEmail"=>"support#coulombtech.com", "FaultReportEmail"=>"support#coulombtech.com", "IsRestrictedEdit"=>nil, "ID"=>5, "Title"=>"ChargePoint (Coulomb Technologies)"}, "OperatorsReference"=>nil, "UsageTypeID"=>1, "UsageType"=>{"IsPayAtLocation"=>nil, "IsMembershipRequired"=>nil, "IsAccessKeyRequired"=>nil, "ID"=>1, "Title"=>"Public"}, "UsageCost"=>"free", "AddressInfo"=>{"ID"=>112837, "Title"=>"1 Locks Plaza", "AddressLine1"=>"1 Locks Plaza", "AddressLine2"=>nil, "Town"=>"Lockport", "StateOrProvince"=>"New York", "Postcode"=>"14094", "CountryID"=>2, "Country"=>{"ISOCode"=>"US", "ContinentCode"=>"NA", "ID"=>2, "Title"=>"United States"}, "Latitude"=>43.169316400362, "Longitude"=>-78.6954369797903, "ContactTelephone1"=>nil, "ContactTelephone2"=>nil, "ContactEmail"=>nil, "AccessComments"=>"Located at the Lockport Municipal building, \"The Big Bridge\" and the \"Flight of Five\" locks 34 and 35 on the Erie Canal.", "RelatedURL"=>nil, "Distance"=>nil, "DistanceUnit"=>0}, "NumberOfPoints"=>1, "GeneralComments"=>"Located at the \"Big Bridge\" and \"Flight of Five\" locks 34 and 35 and the Lockport Municipal building", "DatePlanned"=>nil, "DateLastConfirmed"=>nil, "StatusTypeID"=>50, "StatusType"=>{"IsOperational"=>true, "IsUserSelectable"=>true, "ID"=>50, "Title"=>"Operational"}, "DateLastStatusUpdate"=>"2018-11-04T12:56:00Z", "DataQualityLevel"=>1, "DateCreated"=>"2018-11-04T05:18:00Z", "SubmissionStatusTypeID"=>200, "SubmissionStatus"=>{"IsLive"=>true, "ID"=>200, "Title"=>"Submission Published"}, "UserComments"=>[{"ID"=>20389, "ChargePointID"=>112491, "CommentTypeID"=>10, "CommentType"=>{"ID"=>10, "Title"=>"General Comment"}, "UserName"=>"Robert Seemueller", "Comment"=>"Located next to the Erie Canal's \"Flight of Five\" locks, downtown shops and restaurants.", "Rating"=>5, "RelatedURL"=>nil, "DateCreated"=>"2018-11-04T05:22:02.4Z", "User"=>{"ID"=>19108, "IdentityProvider"=>nil, "Identifier"=>nil, "CurrentSessionToken"=>nil, "Username"=>"Robert Seemueller", "Profile"=>nil, "Location"=>nil, "WebsiteURL"=>nil, "ReputationPoints"=>289, "Permissions"=>nil, "PermissionsRequested"=>nil, "DateCreated"=>nil, "DateLastLogin"=>nil, "IsProfilePublic"=>nil, "IsEmergencyChargingProvider"=>nil, "IsPublicChargingProvider"=>nil, "Latitude"=>nil, "Longitude"=>nil, "EmailAddress"=>nil, "EmailHash"=>nil, "ProfileImageURL"=>"https://www.gravatar.com/avatar/d8475a6af1852aa7fb2e1263c4ae5fac?s=80&d=mm", "IsCurrentSessionTokenValid"=>nil, "APIKey"=>nil, "SyncedSettings"=>nil}, "CheckinStatusTypeID"=>10, "CheckinStatusType"=>{"IsPositive"=>true, "IsAutomatedCheckin"=>false, "ID"=>10, "Title"=>"Charged Successfully"}}], "PercentageSimilarity"=>nil, "Connections"=>[{"ID"=>158246, "ConnectionTypeID"=>1, "ConnectionType"=>{"FormalName"=>"SAE J1772-2009", "IsDiscontinued"=>nil, "IsObsolete"=>nil, "ID"=>1, "Title"=>"J1772"}, "Reference"=>nil, "StatusTypeID"=>50, "StatusType"=>{"IsOperational"=>true, "IsUserSelectable"=>true, "ID"=>50, "Title"=>"Operational"}, "LevelID"=>2, "Level"=>{"Comments"=>"Over 2 kW, usually non-domestic socket type", "IsFastChargeCapable"=>false, "ID"=>2, "Title"=>"Level 2 : Medium (Over 2kW)"}, "Amps"=>nil, "Voltage"=>nil, "PowerKW"=>nil, "CurrentTypeID"=>nil, "CurrentType"=>nil, "Quantity"=>2, "Comments"=>nil}], "MediaItems"=>[{"ID"=>16951, "ChargePointID"=>112491, "ItemURL"=>"https://s3-ap-southeast-2.amazonaws.com/openchargemap/images/US/OCM112491/OCM-112491.orig.2018110405191125.jpg", "ItemThumbnailURL"=>"https://s3-ap-southeast-2.amazonaws.com/openchargemap/images/US/OCM112491/OCM-112491.thmb.2018110405191125.jpg", "Comment"=>"", "IsEnabled"=>true, "IsVideo"=>false, "IsFeaturedItem"=>false, "IsExternalResource"=>false, "MetadataValue"=>nil, "User"=>{"ID"=>19108, "IdentityProvider"=>nil, "Identifier"=>nil, "CurrentSessionToken"=>nil, "Username"=>"Robert Seemueller", "Profile"=>nil, "Location"=>nil, "WebsiteURL"=>nil, "ReputationPoints"=>289, "Permissions"=>nil, "PermissionsRequested"=>nil, "DateCreated"=>nil, "DateLastLogin"=>nil, "IsProfilePublic"=>nil, "IsEmergencyChargingProvider"=>nil, "IsPublicChargingProvider"=>nil, "Latitude"=>nil, "Longitude"=>nil, "EmailAddress"=>nil, "EmailHash"=>nil, "ProfileImageURL"=>"https://www.gravatar.com/avatar/d8475a6af1852aa7fb2e1263c4ae5fac?s=80&d=mm", "IsCurrentSessionTokenValid"=>nil, "APIKey"=>nil, "SyncedSettings"=>nil}, "DateCreated"=>"2018-11-04T05:19:00Z"}, {"ID"=>16952, "ChargePointID"=>112491, "ItemURL"=>"https://s3-ap-southeast-2.amazonaws.com/openchargemap/images/US/OCM112491/OCM-112491.orig.2018110405224211.jpg", "ItemThumbnailURL"=>"https://s3-ap-southeast-2.amazonaws.com/openchargemap/images/US/OCM112491/OCM-112491.thmb.2018110405224211.jpg", "Comment"=>"", "IsEnabled"=>true, "IsVideo"=>false, "IsFeaturedItem"=>false, "IsExternalResource"=>false, "MetadataValue"=>nil, "User"=>{"ID"=>19108, "IdentityProvider"=>nil, "Identifier"=>nil, "CurrentSessionToken"=>nil, "Username"=>"Robert Seemueller", "Profile"=>nil, "Location"=>nil, "WebsiteURL"=>nil, "ReputationPoints"=>289, "Permissions"=>nil, "PermissionsRequested"=>nil, "DateCreated"=>nil, "DateLastLogin"=>nil, "IsProfilePublic"=>nil, "IsEmergencyChargingProvider"=>nil, "IsPublicChargingProvider"=>nil, "Latitude"=>nil, "Longitude"=>nil, "EmailAddress"=>nil, "EmailHash"=>nil, "ProfileImageURL"=>"https://www.gravatar.com/avatar/d8475a6af1852aa7fb2e1263c4ae5fac?s=80&d=mm", "IsCurrentSessionTokenValid"=>nil, "APIKey"=>nil, "SyncedSettings"=>nil}, "DateCreated"=>"2018-11-04T05:23:00Z"}, {"ID"=>16953, "ChargePointID"=>112491, "ItemURL"=>"https://s3-ap-southeast-2.amazonaws.com/openchargemap/images/US/OCM112491/OCM-112491.orig.2018110405240797.jpg", "ItemThumbnailURL"=>"https://s3-ap-southeast-2.amazonaws.com/openchargemap/images/US/OCM112491/OCM-112491.thmb.2018110405240797.jpg", "Comment"=>"", "IsEnabled"=>true, "IsVideo"=>false, "IsFeaturedItem"=>false, "IsExternalResource"=>false, "MetadataValue"=>nil, "User"=>{"ID"=>19108, "IdentityProvider"=>nil, "Identifier"=>nil, "CurrentSessionToken"=>nil, "Username"=>"Robert Seemueller", "Profile"=>nil, "Location"=>nil, "WebsiteURL"=>nil, "ReputationPoints"=>289, "Permissions"=>nil, "PermissionsRequested"=>nil, "DateCreated"=>nil, "DateLastLogin"=>nil, "IsProfilePublic"=>nil, "IsEmergencyChargingProvider"=>nil, "IsPublicChargingProvider"=>nil, "Latitude"=>nil, "Longitude"=>nil, "EmailAddress"=>nil, "EmailHash"=>nil, "ProfileImageURL"=>"https://www.gravatar.com/avatar/d8475a6af1852aa7fb2e1263c4ae5fac?s=80&d=mm", "IsCurrentSessionTokenValid"=>nil, "APIKey"=>nil, "SyncedSettings"=>nil}, "DateCreated"=>"2018-11-04T05:24:00Z"}], "MetadataValues"=>nil, "IsRecentlyVerified"=>true, "DateLastVerified"=>"2018-11-04T05:22:02.4Z"} ChargingStations.find_sites('WA').count => 1
In general, when you use the construct for foo in fooArray to iterate over a Array, the foo is not the index but the actual item located in that position. So if you wanted your algorithm to work with minimal modifications, the "right" way would look like: ##pois.each_index do |i| puts ##pois[i] // rest of the algorithm ommited end In your case, assuming that the structure of your JSON data is something like [{lat: 10, lng: 10},{lat:5, lng:8}, {lat: 9, lng: -3], you are basically trying to do ##pois[{lat: 10, lng: 5}]], which will give you the exact "no implicit conversion" error that you're getting. You could just use i directly like puts i or i["AddressInfo"]["StateOrProvince"] and get the right answer. However, as it has been mentioned in the comments, a more idiomatic approach would be ##pois.each do |poi|. And an even more idiomatic approach would be to rename that ugly-looking "pois" everywhere and make it ##positions.each do |position| puts position if position["AddressInfo"]["StateOrProvince"] == "New York" puts position end end Explicit variable names is the Ruby thing to do :) And assuming the first puts is just a general test to see it's working and you actually want to only print the ones that are in New York... ##positions.each do |position| puts position if position["AddressInfo"]["StateOrProvince"] == "New York" end And if you want to make that a one liner: ##positions.each { |pos| puts pos if pos["AddressInfo"]["StateOrProvince"] == "New York" } (yeah, I know I just talked about explicit variable names but there is no need to be too rigid about it)
Rails 5: group datetime in hash of year, month, day
I have this query: dates = MyModel.pluck("distinct date(datetime_column)") Hash[dates.group_by(&:year).map{|y, items| [y, items.group_by{|d| d.month}]}] which find distinct dates and then gives me this array: => {2017=>{12=>[Tue, 12 Dec 2017], 1=>[Sun, 01 Jan 2017]}, 2016=>{11=>[Sun, 20 Nov 2016], 12=>[Sat, 24 Dec 2016, Mon, 12 Dec 2016, Fri, 30 Dec 2016]}} How do I add 3rd level to have hash where there are particular days under each month? Thank you for any help! Update If someone needs ordered result, try this for "dates" part: dates = MyModel.order(:datetime_column).distinct.pluck(:datetime_column) For better performance can try to use this: dates = MyModel.order("date_trunc('day', datetime_column) DESC") .distinct.pluck("date_trunc('day', datetime_column)") Here is nice blog post on using datetrunc.
You can use each_with_object, but you need to initialize the object correctly. It's a Hash of Hashes of Hashes! require 'date' a = Date.today b = Date.new(2017,1,3) c = Date.new(2015,12,5) d = Date.new(2015,11,7) dates = [a,b,c,d] hash = Hash.new { |h, y| h[y] = Hash.new { |h2, m| h2[m] = {} } } dates_by_ymd = dates.each_with_object(hash) do |date, h| h[date.year][date.month][date.day] = date end require 'pp' pp dates_by_ymd # {2017=> # {1=> # {7=>#<Date: 2017-01-07 ((2457761j,0s,0n),+0s,2299161j)>, # 3=>#<Date: 2017-01-03 ((2457757j,0s,0n),+0s,2299161j)>}}, # 2015=> # {12=>{5=>#<Date: 2015-12-05 ((2457362j,0s,0n),+0s,2299161j)>}, # 11=>{7=>#<Date: 2015-11-07 ((2457334j,0s,0n),+0s,2299161j)>}}} In your case, you'd write : dates = MyModel.pluck("distinct date(datetime_column)") hash = Hash.new { |h, y| h[y] = Hash.new { |h2, m| h2[m] = {} } } dates_by_ymd = dates.each_with_object(hash) do |date, h| h[date.year][date.month][date.day] = date end Note that this code returns Date objects as leaves of the nested hash, as you mentioned in your question. If you want a modified version of your code, you can use this Rails code : dates.group_by(&:year).map do |y, items| [y, items.group_by(&:month).map { |m, days| [m, days.index_by(&:day)] }.to_h] end.to_h
Try dates = MyModel.pluck("distinct date(datetime_column)") dates.group_by(&:year).map do |y, items| [y, items.group_by(&:month).map { |m, days| [m, days.map(&:day)] }.to_h] end.to_h
Rake task to update specific products in db
Hi all I've got a database full of products and I need to schedule a rake task to run every week. I'm not exactly sure how to code the rake task. An example would be I have a product with id=1 name="testname" description="description" sku="198" price=12.99 I need to upload a csv with name="testname" and update the price to 13.99 while obviously keeping the id intact. This is what I've tried so far but its not complete if anyone could help that would be great. require 'csv' desc "Updates Products inside an ActiveRecord table" task :update_prods, [:filename] => :environment do products = Spree::Product.all CSV.foreach('update_prods.csv', :headers => true) do |row| Spree::Product.update!(row.to_hash) end end
Here is a gist of how we imported products from Shopify to Spree which could give you some ideas on how to go about this https://gist.github.com/dgross881/b4f1ac96bafa2e29be7f. def update_products puts 'Updating Products...' require 'csv' products_csv = File.read(Rails.root.join('lib/assets/products_list.csv')) products = CSV.parse(products_csv, headers: true) products.each_with_index do |row, index| Rails.logger.info { [#{index + 1}..#{products.length}] Updating product: #{row['title']} } product = Spree::Product.find!(row['id']) update_product = product.update_attributes(name: row['title'], description:row['description'], meta_title: row['seo_title'], meta_description: row['seo_description'], meta_keywords: "#{row['handle']}, #{row['title']}, the Squirrelz", available_on: Time.zone.now, price: row['price'], shipping_category: Spree::ShippingCategory.find_by!(name: 'Shipping')) update_product.tag_list = row['tags'] update_product.slug = row['handle'] update_product.save! end Rails.logger.info { "Finished Updating Products" } end def update_variants puts 'updating Variants...' require 'csv' products_variants_csv =File.read(Rails.root.join('lib/assets/variants_list.csv')) products_variants = CSV.parse(products_variants_csv, headers: true) products_variants.each_with_index do |row, index| puts "[#{index + 1}..#{products_variants.length}] Adding Variant (#{row['sku']} to Product: #{Spree::Product.find_by!(slug: row['handle']).name})" variant = Spree::Variant.find_by!(sku: row['sku'] update_variant = variant.update_attributes!(sku: row['sku'], stock_items_count: row['qty'], cost_price: row['price'], weight: row['weight'] unless row['option1'].blank? variant.option_values << Spree::OptionValue.find_by!(name: row['option1']) end unless row['option2'].blank? variant.option_values << Spree::OptionValue.find_by!(name: row['option2']) end variant.save! end puts 'Updated Variants' end
Ruby on rails rake task not returning up-to-date model info
While building a billing system I encountered the following problem: In scheduler.rake : #users.each do |user| begin puts "CALCULATING COSTS ==========" costs = user.total_billable_price_per_month(Time.now) lead_count = user.total_billable_leads_count(Time.now) click_count = user.total_billable_clicks_count(Time.now) puts "CREATING NEW INVOICES =======" #invoice = user.invoices.new # if user.free_credits # invoice.total_price_in_cents = 0 # else # invoice.total_price_in_cents = costs.cents # end #invoice.total_leads = lead_count #invoice.total_clicks = click_count #invoice.total_price_in_cents = costs.cents # Als de vorige factuur onder de 10 euro was, dan geld bij huidige factuur optellen if user.invoices.last && user.invoices.last.total_price_in_cents < 1000 puts "Bedrag onder 10 euro" puts "Last invoice = #{user.invoices.last.total_price_in_cents}" #invoice.total_price_in_cents += user.invoices.last.total_price_in_cents end puts "SAVING INVOICE FOR #{user.name} with ID = #{user.id}" # Factuur saven #invoice.save #Als de factuur hoger of gelijk is als 10euro, dan factuur aanmaken if #invoice.total_price_in_cents >= 1000 #Moneybird factuur versturen puts "COSTS ARE HIGHER THAN 10 EURO, CREATING MONEYBIRD INVOICE" moneybird_invoice = MoneybirdInvoice.new sleep(15) moneybird_invoice.contact_id = MoneybirdContact.find_by_customer_id(user.id).id sleep(15) moneybird_invoice.details_attributes = [ { :description => "Aantal leads", :amount => lead_count, :price => user.lead_price.cents.to_f/100}, { :description => "Aantal clicks", :amount => click_count, :price => user.click_price.cents.to_f/100} ] puts "TRYING TO SAVE MONEYBIRD INVOICE" if moneybird_invoice.save && moneybird_invoice.put(:send_invoice) puts "SUCCESFULLY SAVED INVOICE" #GET UPDATED PAY URL #sent_mb_invoice = MoneybirdInvoice.get(moneybird_invoice.id) sleep(15) #invoice.update_attributes(:moneybird_invoice_id => #sent_mb_invoice['invoice_id'], :moneybird_pay_url => #sent_mb_invoice['pay_url']) else puts "MONEYBIRD INVOICE FAILED" puts moneybird_invoice.errors.inspect end else # GEEN MONEYBIRD FACTUUR AANMAKEN end rescue puts "ER IS IETS FOUT GEGAAN MET FACTUREREN USER ID = #{user.id} & NAME = #{user.name}" puts #invoice.errors.inspect end end This piece of code should constantly increment each time the rake task is run, except when the total amount reaches > 1000. if user.invoices.last && user.invoices.last.total_price_in_cents < 1000 puts "Bedrag onder 10 euro" puts "Last invoice = #{user.invoices.last.total_price_in_cents}" #invoice.total_price_in_cents += user.invoices.last.total_price_in_cents end The code above always puts "Last invoice = 100" => This should increment each time the rake tasks is run Every new invoice still has the same total_price_in_cents (when I'm expecting that it should increment). What is going on ?
EDIT: Added after code upadte: In your updated code, it looks like you were calling user.invoices.last after you called user.invoices.new, this is why it always returned the same value. Create a variable #last_invoice = user.invoices.last before call user.invoices.new. ORIGINAL ANSWER: In your original code posting, it looks like your save call on #invoice happened outside the loop -- I believe you're only saving it once. task :create_invoices => :environment do # Begin the loop for each use User.all.each do |user| #invoice = user.invoices.build #If last bill < 1000 if user.invoices.last && user.invoices.last.total_price_in_cents < 1000 puts "Last invoice = #{user.invoices.last.total_price_in_cents}" #invoice.total_price_in_cents += user.invoices.last.total_price_in_cents #invoice.save end # end 'if' statement end # end loop for all users end # end task definition So you loop though the users table, but never save updates -- except for the very last time after you exit the loop