Sunday, May 13, 2012

Rails3, upgrading to OS X Lion and Postgres failing to connect afterwords

I like my post subjects long.  :)

I recently upgraded my computer to Lion from Snow Leopard and after doing this I fired up the rails server to get some work done and everything looked like it was working, nice! Then I tried to load a page from the server and it failed to connect to postgres sql server, not so nice.

This post http://bradleyayers.blogspot.com.au/2011/07/repairing-postgresql-after-upgrading-to.html covers most of what was wrong.

The trouble was before I got to that post I had tried un-installing the pg gem (gem uninstall pg I believe is what I chose and then picked all versions).

One quick not on the link above, make sure you change 9.0 to 9.1 in the paths (or whatever version you're on), I did a quick copy and paste and it found the executable but not the data and I was tired and didn't realize what was going on for a moment.

SO.  Getting back to the problem I created for myself, I had no pg gem and gem install pg now fails.  Why? I had XCode installed but it turns out my dev tools (or paths to them) were wiped out in the upgrade.

The quick answer? Open the "App Store", search for XCode and install the latest version (it's free).  Then I went ahead and installed the command line development tools and restarted terminal before trying anything else ala this post http://stackoverflow.com/questions/10344821/gem-install-pg-doesnt-work-on-osx-lion

Problem solved and I'm back on my way to railsy postgressiveness.

Or something like that.  Hope this helps someone or something!

Monday, April 30, 2012

Git, multiple projects with similar features or roots

Todays post is about how I found a blog post that describes how to use git to branch to a new project and then run both projects simultaneously while still being able to pull new features from one to the other.

The essence of all of this is held in this awesome post: http://programblings.com/2008/07/21/setting-up-a-long-term-fork-with-git/

Really I just use that straight up.  The only thing that confused me a bit is how to use it properly.  I was finding that it was hard to maintain the link between the two depots without accidentally bringing changes across that were not meant to be.

For instance, my database connection strings.  After the fork I changed them to point to my new (but similar) projects new DB.  Then I developed a couple of fixes so I pushed them to my "connecting" depot, merged and pushed to my old depot.  I have just now over-written my db connection strings.  Whoops.

My answer? To make any changes that might be a feature I want to bring across in a branch.  It is far easier to cherry pick changes from a branch than to figure out all the different CL's I need to bring across. That and I'm no git expert and I still need to read a good book about it so there are several things that are lost on me or seem far more complex than they really are, for example commits, the hash tag, how to nicely view a list of them, how to use them properly.  Every example I've seen uses bash scripting voodoo (ok, it's not that complex) to get the hash tag to flow from one git command to the next, in perforce it was just an easy to read and distinguish number I could copy and paste and understand as a human, I liked that.

Rant over.

So, for my own reference, the exercise for the user was possibly to create your own working copy.

mkdir working_copy
cd working_copy
git init
git remote add origin /path/to/repo
git pull origin master

That does that, depending on which repo you want, add that path as the origin.

Next, cherry picking without having to work out all the hashes.

git gui

That's pretty much the answer.  I will explain how I personally do it in the next post.

Thursday, April 26, 2012

Google analytics and variable types

I recently went on a mission to change up how we use google analytics events and I wound up having some problems.  I use chrome as my default browser and there is a great extension called google analytics debugger (by google) that helps immensely when debugging analytics code.  I used it the first time around to set everything up.


function gAnalyticsPush(action, name, id, non_interact)
{
  non_interact = typeof non_interaction !== 'undefined' ? non_interact : false;
  push_id = parseInt(id);
  label = id; // this is a string
  _gaq.push(['_trackEvent', name, action, label, push_id, non_interact]);
}

This is my current code.  I tried setting it up so push_id (integer) would be the name (category in the api docs) and the google debugger said everything was working but, alas, when i uploaded it and found I was no longer getting events I realized it was not.

After a while I ditched sending Id's as my category and started using the name (as for me, the two are essentially the same) so I had this:
function gAnalyticsPush(action, name, id, non_interact)
{
  non_interact = typeof non_interaction !== 'undefined' ? non_interact : false;
  push_id = parseInt(id);
  _gaq.push(['_trackEvent', name, action, push_id, push_id, non_interact]);
}

But that wasn't working either.  The problem wound up being that I couldn't send an integer type in the label parameter.  I changed the above code from push_id to just id and it STILL  wasn't working.  I then guaranteed that all id parameters being sent to my gAnalyticsPush function had quotes around them and SHAZZAM, everything worked.

I'm sure that I could solve this in the function but right now there is no need for me to do it.

So I call the above function like so (inside a script tag):

gAnalyticsPush('something_viewed','<%= @model.name %>','<%= @model.id %>',true);

Note that those quotes around the model id are quite important and google analytics debugger did not report any errors even when things were not working.

Monday, April 23, 2012

Rails 3, Ransack and additional query criteria

I'm not exactly sure what the name of what I'm doing is so "additional query criteria" is what it came down to.

I have a table, I want to let users search through it but I only want them to search their records.

I'm using ransack for the searching and it's quite nice, it let me get the search up and running very quickly and it has more power than I really need.  What it didn't have was the ability to require a search term to be a specific value.  I should rephrase, the documentation did not have this.  Without this ability my users will search through everyones data and see things they shouldn't.

Normally I'd use a scope or something like it to make sure user_id = current_user.user_id but how do I do this with ransack?

The answer I'm currently using is to high-jack the query parameter and add my criteria before passing it on to the search method of my model.

That looks something like this:


if params[:q]
  params[:q]["user_id_eq"] = current_user.id
  @q = Customer.search(params[:q])
  @customers = @q.result(:distinct => true)
end

And that's it, now my query has my additional requirements tacked on.

[edit]

OK, so I guess I'm an idiot.  https://github.com/ernie/ransack/wiki/Basic-Searching clearly shows how to do this.  The above could probably be shortened to

  @q = Customer.search(params[:q].merge({"user_id_eq" => current_user.id})

Or something like that anyway

Tuesday, April 17, 2012

An update to the jquery live() function post from before

This isn't a big update.

Just a note.  In a previous post (http://coderambled.blogspot.com.au/2012/03/jquery-coffeescript-and-javascript-html.html) I talked about how my form wasn't answering to click events and whatnot if it was populated using ajax type loading and the answer was the .live function.

Turns out this is deprecated, better to use .on


$(document).on('click', '#form_submit', function() {

    $("#animation").html("<img src='/images/ajax-loader.gif' />");

});


That is my preferred way to do it.  No coffeescript this time because I'm editing a rails 3.0 project.

Also I learned that each release of jquery_ui has a list of where it's hosted on content delivery networks.

http://stackoverflow.com/questions/4944293/jquery-liveclick-vs-click has some good code snippets on the subject

Wednesday, April 11, 2012

Rails, ActiveRecord and using []= operator on string and then saving the record doesn't save!

The whole problem is listed in the title.

Yesterday I was trying to update some fields in my database replacing strings within them and then saving.

records = Model.all
records.each do |record|
  record["somestring"] = otherString
  record.save!
end

This code results in no saves to the database? Why?

From what I found searching the internet (sorry, I'm not really interested in debugging ruby to find out at this point) the assignment operator is used to figure out if a field has changed and needs saving to the database.  Well, I never specifically use the assignment operator and my guess is this is why rails doesn't think it's changed.

The answer (this could likely be nicer but it's just temp code so I bruteforce'd it)


records = Model.all
records.each do |record|
  str = record.field.dup
  record.field["somestring"] = otherString
  record.field = str
  record.save!
end

That did the trick.  It works.  I would call this a bug but it's possible there was a reason for this.  I'm also not certain if it's possible to set the the field to be changed without using the assignment operator.

Tuesday, April 3, 2012

select distinct sql vs select with group by

Yesterday while trying to modify a query I had a bit of a realization about queries with DISTINCT in them and it seems simple and I probably even realized it before and forgotten, it wasn't a ground breaking realization but useful.

SELECT DISTINCT column_name FROM table

is basically the same as

SELECT column_name FROM table GROUP BY column_name

This was taken from one of my favourite query types, the nested query using union logic:

SELECT table.* FROM table WHERE id in (SELECT DISTINCT id FROM maybe_other_table WHERE lots_of_stuff)

That's it, I could probably comment on how they are implemented but you can search the internet for that, I usually just see what stackoverflow has to say about it, here you go http://stackoverflow.com/questions/581521/whats-faster-select-distinct-or-group-by-in-mysql

Peace.

Friday, March 30, 2012

Rails 3. and rspec not doing what I expected

I'm trying to be better, at writing tests.  When I develop, especially for myself, I don't always know exactly how something will work or fit together exactly so I search with code for a while to find what I want.  It's hard to write a "red-green" test for this style.  I'm also not used to it as a lot of the work I have done in my past didn't have a test bed to do these kinds of tests.  So I'm bad at getting myself to write tests....blah, blah

So I was actually writing some tests with rspec and rails and they were failing, and I'm not expert at either rspec or rails and so a lot of things seem like "magic", ie get :index and suddenly a response variable shows up.

Anyway, I was testing a :post command and it should have been rendering a page after that.  I was trying to test the page rendered after the post.

response.should have_selector("form", :method => "post") do |form|          
   form.should have_selector("div", :class => "actions") do |div|            
     div.should have_selector("input", :value => "Create")
   end
end


And it just wasn't working, I was testing for information in the rendered page and it just wasn't there.  I dumped the response variable (puts response.inspect) and there was a lot of info there but clearly not the page I was expecting.  Then I dumped the header or head or something, can't remember and it clearly showed text that I was going to save but didn't, sorry, that said it was redirecting me.  Ahh! The answer, the post throws me to a redirect and I'm testing that page, it all makes sense! So now I'm testing that the redirect is going to the right spot and the other pages are tested a different way.

response.should redirect_to(subscribe_listing_purchases_path(Listing.last))

The end.

Sunday, March 25, 2012

Jquery, coffeescript and the javascript .html() working, and then not working

I ran into this problem where I made a form that had some jquery/javascript niceness to it that load up different forms when the users selects different links.  These forms have javascript/jquery of their own and all the code was there but it wasn't firing? WTF?

Well, it makes some sense because when the jquery code is initially run the form it's supposed to bind to isn't there.

So what now?

Answer, .live(), coffescript:

$ -> $("#my_id").live 'change', ->
if(this.checked)
$("#other_id").show()
else
$("#other_id").hide()


This makes the jquery goodness bind to all current and future instances with the given id.  Now the form that is loaded by user interaction has it's javascript functioning.


Saturday, March 24, 2012

Heroku, nginx, ec2, logs and awstat

That's a lot of crap in the title. I searched the internet far and wide for answers to why it doesn't just "work" but no dice.  So here it is, on the internet.  The answer mostly lies in the LogFormat string in the config.

I'm using heroku, I managed to get everything setup so my logs get shipped off to an ec2 instance.  Nice.

Now the problem I was having is trying to interpret the logs to get something like awstat to understand them.

Step 1, grep the log file and dump all the nginx output to a file

grep nginx file.log > nginx_only.file.log

I was trying to run something like this,

awstats.pl -config=model -output -staticlinks > awstats.model.html


And of course running into issues. First tip, take off all the arguments to awstats.pl that I was using, keep -config (which is mandatory), you'll get better error output although still not totally useful.  To generate the config file above I just ran the config script provided with the awstats tarball.

SO, clearly the output was telling me that my LogFormat is not correct. Standard apache output won't work? NO! Not from heroku it won't.

After a bunch of fiddling this seems to be working for me, some of the fields may be used incorrectly but it's a start for anyone looking

LogFormat="%time3 %host_r %other %other %host %other %other %time1 %methodurl %code %bytesd %refererquot %uaquot %virtualname"


Will match

Jan 24 12:07:53 d.b194-8831e521ea77 heroku[nginx] - 192.10.192.10 - - [24/Jan/2012:12:07:53 +0000] "GET /javascripts/application.js?1327406636 HTTP/1.1" 200 1001 "http://www.domain.com/" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" www.domain.com
 " 
One last last little note: the log has a bunch of dashes ("-"), I tried to capture those by putting a dash in the LogFormat string, this is incorrect, capture them by using %other.

The End.
So I've tried to start embracing coffeescript that is used in Rails 3.1, I guess it's the thing to do or something.

Anyway, I'm also using the jquery and that's all good and fine. The issue I was having is this:

I've got a form and I want it to be as easy as possible for the user to understand it and fill it out. I've got a dropdown box (or select) on this form and depending on the value I want to make little changes in the form take place to make the form easier for the user.

No problem, add some jquery to handle the change() event, show() or hide() somethings and shazam, things make more sense.

Great. So now the user saves the form and comes back to it to edit something and all those little changes that were made are no longer there. Hrm. Well, I could set the initial state of the form by adding a bunch of code to set the default values of the style's and whatever else needs to be changed but this is ugly and means putting style or js code in my view which I would rather not do.

So why not just add some code to handle the ready() event on the page, problem is the dom is initialized but the values in the form have not been set yet and my function relies on those values to work properly. I then fiddled around with trying to get a function to be called after the page was finished loading and rendering and all that but nothing was working well.

Then I found a tip on the internet suggesting to just call the change() function on the form element from the ready() event of the page. Seems like it wouldn't work because the values are not set but it turns out the change call is only handled after everything (well, everything that I need) is setup so boom. Fixed and no ugliness!

The coffeescript code:

$ -> $('#my_id').change()