fullcalendar with rails - limit results to a range - ruby-on-rails

I've got fullcalendar working with a small rails app (yeah) but it's sluggish because the find in my controller is finding ALL the records before it renders the calendar. I'm using a JSON approach. The field names I'm using are starts_at and ends_at. This (in the index method of the assignments_controller) works:
#assignments = Assignment.find(:all, :conditions => "starts_at IS NOT NULL")
But, as I said, it's pokey, and will only get worse as more records get added.
So this is clearly more of a rails question than a fullcalendar question: I can't figure out how to get fullcalendar to initially display the current week (when no parameters have been sent) and then accept parameters from next/previous buttons while, in either case, only looking up the relevant items from the database.
Oh - this is rails 2.x, NOT 3.
Thanks for any pointers.

Please ignore this question.
It turned out to be an issue with Date format inconsistencies between JavaScript (Epoch) and Ruby. At least that's what I think at the moment.
I'm still scratching my head, trying to figure out how exactly I "fixed" it, but it seems to be working.
I was aware of this project: http://github.com/bansalakhil/fullcalendar
but it took me ages to get the nuance of Time.at figured out.
I must say, Time is a tricky thing.
In real life as well as in code.
Thanks to everyone who gave my (misguided, as it turned out) question a glance.

Related

Trying to test my nested Rails 5 form (mintest)

The actual nested form itself works fine, but i'd like to be able to have a test covering it to make sure I don't screw it up later. I also have more nested forms planned so I'd really like to figure this out.
I'm getting this failing test in my ListControllerTest:
"ListItem.count" didn't change by 1.
Expected: 1
Actual: 0
With this code:
https://pastebin.com/BRdtZW2T
Note that the "List.count" bit does pass. Again, this does actually work exactly as it's supposed to. I can create lists with lists items no problem when I actually submit forms on my app.
Lists are created with form_for
ListItems are created with fields_for
Figured it out. First off, I removed 'list_item_attributes' from the params being posted in my test. It seemed redundant, and I wasn't sure why I added it in there until I removed it, and my tests raised a different error:
TypeError: no implicit conversion of Symbol into Integer
app/controllers/lists_controller.rb:15:in `[]'
No idea what this was about, but some google searches turned up this:
http://billpatrianakos.me/blog/2013/09/29/rails-tricky-error-no-implicit-conversion-from-symbol-to-integer/
Which as it turns out is exactly my problem. So I added some extra square [] brackets to my params:[:list][:list_item], and presto it worked. See the revised pastebin as well as the article because that probably wasn't clear:
https://pastebin.com/uxRjsctK

Updating a lot of records frequently

I have a Rails 3 app that has several hundred records in a mySQL-DB that need to be updated multiple times each hour. The actual updating is done through delayed_job which is triggered in controller-logic (checking if enough time has passed since the last update, only then sth. happens).
Each update is slow, it can take up to a second in some cases (although it averages at 3 - 5 updates/sec.).
Code looks like this:
class Thing < ActiveRecord::Base
...
def self.scheduled_update
Thing.all.each do |t|
...
t.some_property = new_value
t.save
end
end
end
I've observed that the execution stalls after 300 - 400 records and then the delayed job just seems to hang and times out eventually (entries in delayed_job.log). After a while the next one starts, also fails, and so forth, so not all records get updated.
What is the proper way to do this?
How does Rails handle database-connections when used like that? Could it be some timeout issue that is not detected/handled properly?
There must be a default way to do this, but couldn't find anything so far..
Any help is appreciated.
Another options is update_all.
Rails is a bad choice for mass data records. See if you can create a sql stored procedure or some other way that would avoid active record.
Use object.save_with_validation(false) if you are ok with skipping validations altogether.
When finding records, use :select => 'a,b,c,other_fields' to limit the fields you want ('a', 'b', 'c' and 'other' in this example).
Use :include for eager loading when you are initially selecting and joining across multiple tables.
So I solved my problem.
There was some issue with the rails-version I was using (3.0.3), the Timeout was caused by some bug I suspect. Updating to a later version of the 3.0.x branch solved it and everything runs perfectly now.

Concurrency and Mongoid

I'm currently trying my hand at developing a simple web based game using rails and Mongoid. I've ran into some concurrency issues that i'm not sure how to solve.
The issue is i'm not sure how to atomically do a check and take an action based upon it in Mongoid.
Here is a sample of the relevant parts of the controller code to give you an idea of what i'm trying to do:
battle = current_user.battle
battle.submitted = true
battle.save
if Battle.where(opponent: current_user._id, submitted: true, resolving: false).any?
battle.update_attribute(:resolving, true)
#Resolve turn
A battle is between two users, but i only want one of the threads to run the #Resolve turn. Now unless i'm completely off both threads could check the condition one after another, but before setting resolving to true, therefore both end up running the '#Resolve turn' code.
I would much appreciate any ideas on how to solve this issue.
I am however getting an increasing feeling that doing user synchronization in this way is fairly impractical and that there's a better way altogether. So suggestions for other techniques that could accomplish the same thing would be greatly appreciated!
Sounds like you want the mongo findAndModify command which allows you to atomically retrieve and update a row.
Unfortunately mongoid doesn't appear to expose this part of the mongo api, so it looks like you'll have to drop down to the driver level for this one bit:
battle = Battle.collection.find_and_modify(query: {oppenent: current_user._id, ...},
update: {'$set' => {resolving: true})
By default the returned object does not include the modification made, but you can turn this on if you want (pass {:new => true})
The value returned is a raw hash, if my memory is correct you can do Battle.instantiate(doc) to get a Battle object back.

datetime_select with zeroed minutes

I know that I can use the component parts of the date helpers, rather than the full
datetime_select, but I'm not sure how it would work as far as combining the params.
A bit of background, I'm creating an app for traffic monitoring where people can log traffic counts in 1 hour blocks. I'm presenting the user with a datetime_select so they can specify the start of the block, then later I'm calculating the end.
So I don't want people to be able to submit minutes or seconds, well seconds aren't shown with the helper so that's a start.
I've tried to zero it before the record is created with something like:
params[:result]['start(5i)'] = 0
which is the key that the development log shows rails is using for minutes. Unfortunately I get:
undefined method `empty?' for 0:Fixnum
I guess I could do this with some javascript, hide the minutes select box and remove all but the "00" option. I'd rather find a nice, clean solution if I can though.
Grateful for some tips. Happy to provide more information but not sure what else might be of use at the moment.
params are Strings! try this:
params[:result]['start(5i)'] = '0'
or this:
params[:result]['start(5i)'] = ''

Removing duplicates from array before saving

I periodically fetch the latest tweets with a certain hashtag and save them locally. In order to prevent saving duplicates, I use the method below. Unfortunately, it does not seem to be working... so what's wrong with this code:
def remove_duplicates
before = #tweets.size
#tweets.delete_if {|tweet| !((Tweet.all :conditions => { :twitter_id => tweet.twitter_id}).empty?) }
duplicates = before - #tweets.size
puts "#{duplicates} duplicates found"
end
Where #tweets is an array of Tweet objects fetched from twitter. I'd appreciate any solution that works and especially one that might be more elegant...
you can validate_uniqueness_of :twitter_id in the Tweet model (where this code should be). This will cause duplicates to fail to save.
Since it sounds like you're using the Twitter search API, a better solution is to use the since_id parameter. Keep track of the last twitter status id you got from your previous query and use that as the since_id parameter on your next query.
More information is available at Twitter Search API Method: search
array.uniq!
Removes duplicate elements from self. Returns nil if no changes are made (that is, no duplicates are found).
Ok, turns out the problem was a bit of different nature: When looking closer into it, I found out that multipe Tweets were saved with the twitter_id 2147483647... This is the upper limit for integer fields :)
Changing the field to bigint solved the problem. It took me very long to figure out since MySQL did silently fail and just reverted to the maximum value as long as it could. (until I added the unique index). I quickly tried it out with postgres, which returned a nice "Integer out of range" error, which then pointed me to the real cause of the problem here.
Thanks Ben for the validation and indexing tips, as they lead to much cleaner code now!

Resources