Fixing: PG::UniqueViolation: ERROR: Duplicate Key Value Violates Unique Constraint ‘Your_table_name_pkey’

Published on:

Issue

Postgresql maintain a internal value which is the max value of the id column of a given table. And uses this to generate values for primary keys when you insert new records. Sometimes this internally stored value can get messed up. And that can cause the error above when you are trying to insert a new record to the table.

Fix

You need to basically correct the above said value.

[fix]
1
2
3
pg_dump -U user_name database_name -f database_backup_name.sql
cd /your/rails/app/root/
rails db production
[update your_table_id_sql]
1
SELECT setval('your_table_id_seq', (SELECT MAX(id) FROM your_table));

replace your_table with whatever the table name you are using. And the code above assumes your primary key column name is id.

References

Thoughts on Doing a Mobile Web Version of Your Rails App

Published on:
Tags: mobile, rails

Recently i started working on making a mobile web version of one of the in-house rails apps that i have been developing for a while. I’ve never done this before (a mobile web version of a rails app, with separate mobile optimised web pages/views served when you access the site via a mobile device).

The problem was simple enough. Figure out the user agent and then serve the proper view. But then it wasn’t that simple (as always). Googling on how to do this the proper way (rails way..etc) gave me some leads.

Choices

There seems to be two problems that we are faced with here. The first one is figuring out the user agent. This is easy and quite straight forward. You can use a gem to do this for you or you can just DIY. I went the DIY way.

When it comes to displaying/organising the mobile views there seems to be at least three popular approches.

The first option involves you defining a custom MIME type for mobile. This is all fine and dandy but this also means you will end up with .mobile view templates in your view folders. In the same folders that have your normal views. I don’t like this approche purely because i feel this is too messy. Also you can’t share views across the two versions of the site.

Having a custom domain (m.yourapp.com) didn’t appeal to me either. Having just one site with one domain that will look different depending on what devise you use to access it is, IMHO much better.

So i went with the prepend_view_path. Thanks to the blog post by scottwb.com. We have almost finished the mobile site version of our app and so far haven’t come across any major hurdles.

Some notes about using prepend_view_path

  • Recommend reading A Better Way to Add Mobile Pages to a Rails Site
  • You will have app/views and something like app/views_mobile
  • If you have prepend_view_path app/views_mobile rails will first look for a matching template there, and if it can’t find one will fallback to app/views
  • The above applies to assets as well.
  • In my experience it helps to have different application.js and application.css for your mobile version. This will let you only include the stuff thats need for mobile. And also include things that are only needed in mobile, only in the mobile version of the app.
  • You can create something like application.mobile.js and application.mobile.css to include all the assets needed for your mobile web version.
  • Be sure to add the above to files to production.rb like:
[production.rb]
1
2
3
  # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
  # config.assets.precompile += %w( search.js )
  config.assets.precompile += %w[application.mobile.js application.mobile.css]
  • You cab also look in to sensa touch, jquery mobile.. et al. If thats your thing.

Thats all!

SHDH #03 - Super Happy Dev House Singapore

Published on:
Tags: singapore

Super Happy Dev House Singapore 3rd edition was held last saturday (6th April) at the Hub. I went in there around 12.30am (yeah am). And there were about 20-25ish folks hanging around. I wanted to work on a idea that i had in mind for sometime and that was my idea when going there.

It has been a long time since i attended any kind of developer event. And i narrowly missed this one as well. But i am glad i made it because it was fun and i enjoyed it. When i reached everyone have already started working on some project. They have formed groups and busy working on there stuff. I met laktek from action.io there and he was working with some peeps on this tissue paper project Free Tissue. It was a interesting project however i wanted to work on my own thing so i grabbed some coffee and started coding.

I worked on a web UI for Octopress. Now i know that sounds very big and serious but i just worked on a very simple tool that addresses some of my pains with using octopress to blog. And i was able to come out with a ‘MVP’ (something that did the absolute minimum of the core functionality i wanted). It works but isn’t good enough to be released (not that if anyone will really care if i do lol). But kinda happy i got it to this stage. And about the fact that i actually hacked something out in a hackathon. Yeah it was a first for me. I’ve been to the 1st and the 2nd SHDH event in SG. However it was more about socialising and less about coding. This one was different. And the difference made it awesome.

The night was spent coding and discussing thoughts about the hacker scene/node.js/rails and your usual hacker concerns. It was fun and i it rekindled my ‘inner hacker’ spirit lol.

And the swagger was top notch ;)

I just wanna give a big thank you for the organisers of the event. You guys rock! Hope to attend SHDH #04 next year!

Deleting a Uploaded Paperclip Attachment/file in Active Admin

Published on:
Tags:

Was looking for a ‘the way’ of doing this, found none. So improvised. This post is a copy of my answer on stackoverflow.

[models.rb]
1
2
3
4
5
6
7
8
9
10
form :html => { :enctype => "multipart/form-data"} do |f|
f.inputs "Details" do
  f.input :name
  f.input :subdomain
end
f.inputs "General Customisation" do
  f.input :standalone_background,  :hint => (("current image:<br/>").html_safe +   f.template.image_tag(f.object.standalone_background.url(:thumb))).html_safe, :as => :file
  f.input :remove_standalone_background, as: :boolean, required: false, label: "remove standalone background"
 end
end

In your model

You could define a status flag like bellow

[model.rb]
1
2
3
4
5
attr_writer :remove_standalone_background

def remove_standalone_background
  @remove_standalone_background || false
end

OR (depreciated in rails 3.2)

[model.rb]
1
2
3
attr_accessor_with_default : standalone_background,false

before_save :before_save_callback

And

[model.rb]
1
2
3
4
5
def before_save_callback
  if self.remove_standalone_background
    self.remove_standalone_background=nil
  end
end

That does it for me. Not ideal, but it gets the job done.

Rails Application Versioning

Published on:
Tags: rails,, ruby

Back in the days of sub version forks used to use the revision number of the deployed branch or the truck to version the app. I remember stackoverflow.com used this strategy for sometime. Anyways getting back to topic, the QA folks at work wanted a version number for this web application that i am working on right now. Reason been that will allow them to keep track of the application and generally be useful with issue tracking and such.

I looked around for a standard ruby way of doing this. However i didn’t find any. There were some gems that try to handle things for you. Mostly by providing you some rake tasks to increment the major/minor/build…etc versions. But i wanted something that i can just setup and forget about. Like for example using the subversion revision number.

Right now i am using Git. And some folks were using the last commit’s hash as the version number. This is all cool but its not something thats incremental. This can be a problem for humans.

So at first i thought of setting up a git pre commit hook to automatically run a rake task to increment application version number. Pre commit because then i select the version file it self and include it in the commit (there for if i am displaying the version on my site, it will reflect the latest version whenever i commit and deploy my changes). This approach was very straight forward and i soon found my self battling rvm.

This particular application is hosted on heroku. And it turned out that heroku sets a version number internally for each deploy of the application. You can access this as shown bellow. I ended up using a combination of the last commit’s hash and the heroku deploy ‘name’/version for this rail’s application’s version.

[production.rb]
1
2
3
4
5
6
# Heroku API key is in the source!@@#! might not be such a good idea
  heroku_client = Heroku::Client.new '', 'your_api_key_here'
  last_deploy = heroku_client.releases('APP_NAME').last

  # Get the app version using a combination of the deploy version from heroku and the commit hash.
  config.app_version = "#{last_deploy["name"]} #{last_deploy['commit']}"
[development.rb]
1
config.app_version = "development version"

And i can now display the application version anywhere in my views.

[application.html.erb]
1
2
3
4
5
<div id="footer">
  <div class="container">
    <p class="muted credit"><%= Rails.configuration.app_version %></p>
  </div>
</div>

You can do something like the above if you are on heroku. The end result is something like this

v235 82ee972

It can look a bit weird for a normal user, specially the commit hash part. But the heroku deploy version look humane enough.

Enable Auto Save on Sublime Text 2

Published on:
Tags: notes

So recently i have been using sublime for a PHP(!) project. And i missed the auto save feature of rubymine that i am so used to. Turns out that sublime has a similar feature. Its disabled by default though.

You can enable it by: Sublime Text2 -> Preferences -> Settings - Default

Then set:

[Setting]
1
"save_on_focus_lost": true,

Thats it!.

The Performance Cost of MongoDB Safe Inserts and Updates

Published on:

We have been using mongodb and mongomapper for a large scale project that deals with a lot of data. Due to concerns about data integrity we decided to use ‘safe’ inserts and updates with mongo. However this comes at a cost. The bellow paragraph explains what its all about.

Quoting mongomapper documentation:

In MongoDB, database writes/updates follow the “fire and forget” pattern. This means that the database will not wait for a response when you perform an update operation on a document. MongoMapper follows this same convention by default.

The down side of this strategy is if something goes wrong–such as a unique index constraint failing or an internal MongoDB error–an error won’t be raised. You may never know that your data isn’t being saved, until you try to read it and it’s not there.

Instead of just using the default “fire and forget” behavior on our save operation, passing the :safe option to save will force the driver to make sure the save succeeds and raise an error if it doesn’t.

So I decided to do some SIMPLE tests to get a rough idea of how much performance we loose when we do safe inserts/updates over ‘unsafe’ ones.

Here I am using two classes:

TestUser: Mongo document without the safe parameter

[test_user.rb]
1
2
3
4
5
6
class TestUser
  include MongoMapper::Document

  key :name, String
  key :age,  Integer
end

SafeTestUser: Mongo document with the safe parameter

[safe_test_user.rb]
1
2
3
4
5
6
7
class SafeTestUser
  include MongoMapper::Document
  safe

  key :name, String
  key :age,  Integer
end

All tests were run on IRB in my local machine and the mongodb instace was a ec2 server hosted remotely(duh). Used MRI Ruby 1.9.2

100000 inserts were done twise.

[Inserts - Unsafe]
1
2
3
4
5
6
7
8
9
10
11
12
13
1.9.2p290 :035 > Benchmark.measure {
1.9.2p290 :036 >     100000.times {
1.9.2p290 :037 >       SafeTestUser.create(:name => "test_name", :age => "21")
1.9.2p290 :038?>     }
1.9.2p290 :039?>   }
 =>  32.970000   2.090000  35.060000 ( 35.533769)

1.9.2p290 :062 > Benchmark.measure {
1.9.2p290 :063 >          100000.times {
1.9.2p290 :064 >              TestUser.create(:name => "test_name", :age => "21")
1.9.2p290 :065?>          }
1.9.2p290 :066?>      }
 =>  34.060000   2.130000  36.190000 ( 41.372273)
[Inserts - Safe]
1
2
3
4
5
6
7
8
9
10
11
12
13
1.9.2p290 :048 > Benchmark.measure {
1.9.2p290 :049 >          100000.times {
1.9.2p290 :050 >              SafeTestUser.create(:name => "test_name", :age => "21")
1.9.2p290 :051?>          }
1.9.2p290 :052?>      }
 =>  88.620000  13.080000 101.700000 (744.424769)

1.9.2p290 :082 > Benchmark.measure {
1.9.2p290 :083 >          100000.times {
1.9.2p290 :084 >              SafeTestUser.create(:name => "test_name", :age => "21")
1.9.2p290 :085?>          }
1.9.2p290 :086?>      }
 =>  62.410000   9.410000  71.820000 (746.311413)

100000 Updates were done using ‘set’ and then using basic iteration

[Updates using ‘set’ - Unsafe]
1
2
3
4
1.9.2p290 :077 > Benchmark.measure {
1.9.2p290 :078 >          TestUser.set({}, :name => "updatetest")
1.9.2p290 :079?>      }
 =>   0.000000   0.000000   0.000000 (  0.000494)
[Updates using ‘set’ - Safe]
1
2
3
4
1.9.2p290 :088 > Benchmark.measure {
1.9.2p290 :089 >          SafeTestUser.set({}, :name => "updatetest")
1.9.2p290 :090?>      }
 =>   0.000000   0.000000   0.000000 (  0.000396)
[Updates using basic iteration - Unsafe]
1
2
3
4
5
6
7
8
1.9.2p290 :091 > Benchmark.measure {
1.9.2p290 :092 >          TestUser.all.each { |u|
1.9.2p290 :093 >            u.name = "testtesttestname"
1.9.2p290 :094?>     u.age = "251"
1.9.2p290 :095?>     u.save
1.9.2p290 :096?>          }
1.9.2p290 :097?>      }
 => 160.280000   5.940000 166.220000 (168.674940)
[Updates using basic iteration - Safe]
1
2
3
4
5
6
7
8
1.9.2p290 :098 > Benchmark.measure {
1.9.2p290 :099 >          SafeTestUser.all.each { |u|
1.9.2p290 :100 >            u.name = "testtesttestname"
1.9.2p290 :101?>     u.age = "251"
1.9.2p290 :102?>     u.save
1.9.2p290 :103?>          }
1.9.2p290 :104?>      }
 => 104.810000  10.010000 114.820000 (805.641090)

The tests I just did are not the most accurate way of judging the performance of mongo. But I think they give a rough indication of how much of a performance penalty you pay when you opt for safe inserts and updates.

According to what I see above the inserts are 19(19.38) times slower! And the updates are (ignoring the ‘set’ updates) around 5(4.7) times slower.

So i think if you want to use safe updates and inserts you really need to be sure that its worth the performance penalty you have to pay.

Talking to Strangers

Published on:
Tags: personal

I am ‘traditionally’ a shy person. Not overly forward or outgoing personality. I’ve been trying to get out of my shell and be more social. Talk to people, exchange ideas and network. Because after all people are the most interesting ‘machines’ you can find ;)

Since I moved to Singapore work, I’ve been to a good number of developer events. These events bring together developers who share similar interests as I do. Which is grate because I can share with them what i know and learn a lot more things from them. After all thats how we all grow as developers, right?

Been traditionally shy and not very social it was a challenge at first for me to talk to people that I’ve never met let alone talked to. These guys were complete strangers to me. All I knew about them was that they share some interest in the topic(s) of whatever the meet-up.

At first when I go to a event, I feel awkward, out of place and uncomfortable. I look around, see people talking to each other. Its like everybody knows everybody expect me! This doesn’t make things easier for me.

I’ve seen some folks just spend time staring at their phones/laptops. This is one easy thing to do when you don’t know who to talk to. Or feel too uncomfortable to do so. As I found out later this doesn’t help.

If you are not sure how to start a conversation, try asking a question that you have about a topic discussed in the meet-up from someone nearby. For me this feels more natural (IE: if I have a question about something some speaker just said, I’d just ask someone near by to clear my doubts).

Drag a colleague or a friend with you to whatever meet-up you go to. This will make you feel a bit more comfortable. But don’t just talk with your friend throughout the whole meet up. Say hi to some folks you see around.

We tend to think that everyone in a meet-up know everyone, because they seems to be familiar with each other. But this is hardly the case. Most people just come start discussions with other folks they meet for the first time.

Finally the only way to improve your social skills is to actually try being social! There are no shortcuts or a work around. Once you break the ice it can be a fun and rewarding experience.

RedDotRubyConf 2012 Singapore

Published on:

Last weekend (18-19 may 2012) i was at the NUS Cultural Center attending the RedDotRubyConf 2012. It was a fun and inspiring experience for me, just like that last one in 2011. Thankfully my company covered the ticket costs. I went in with 4 more colleagues.

Thought it would be a good idea to jot down some notes about the whole experience.

General

The venue was nice and big, but it was not very easy to get there. Primarily because I needed to take a bus from the closest MRT station. If its near a MRT station or if its in the city area (where you can easily walk from place to place and MRT stations are abundant) it would have been more accessible.

What bugged me the most was that no drinks were allowed inside the conference hall!!! How can I concentrate without my caffeine?!:)

There was no WiFi in the venue. But I think thats OK. I didn’t go there to work or surf FB. And I always have 3G if I need it.

Talks and what I thought about them

So I just ripped of the list of talks from the official site and I am going note down how I felt about each of the talks. These are just my opinions and of course is VERY SUBJECTIVE.

Day One

  • Ilya Grigorik Building a Faster Web - Good
  • Richard Schneeman The 12 factor app - meh
  • Thorben Schroder to come - Nice insight and a lot of swearing ;)
  • Andras Kristof to come - Interesting. But no conclusion, left me hanging. Waiting for a update on how ViKi ended up doing performance testing!
  • Danish Khan to come - hmmm
  • Sau Sheong Chang Ruby, Rock & Roll - Interesting Hackery
  • Winston Teo CSS Can be Tested Too - OK
  • Hemant Kumar Dive Inside Ruby 1.9 - Didn’t get most of it
  • Tim Oxley Benefits of Client-side Templating - Missed it
  • Wei Lu A Journey in Pair Programming - Missed it

Day Two

  • Obie Fernandez Redis on Rails - Good
  • Zach Holman Git+Github Secrets - meh
  • Terence Lee Bundle Y U So Slow? - Good
  • Carl Coryell-Martin to come - ‘Meaning of life’ type talk. Good.
  • Sebastian Burkhard Run Ruby Run - meh
  • Gabe Hollome Level up with Coffeescript - hmmm
  • Darcy Laycock API Driven Applications - Good, technical
  • Michael Koziarski Lessons from the Other Side - Awesome and inspiring talk. Think this was the best talk in the conference!

Personally I source a lot of inspiration from talks in a conference and only a bit of knowledge. I’d read a book if I want to get deep on some tech rather than attending a conference, IMHO.

Attendees

Talked to a bunch of people at the conference. Although I think my social skills can be improved a lot I am relived to affirm my self that i am not a total disaster when it comes to talking to strangers. The crowd was pretty global. Mostly from Asia pacific, US and UK.

Met people from the Philippines, Cambodia, Malaysia, India, China, US, NZ and many more. Its hard to comprehend the scale of the ruby community sometimes. And its always nice to talk to like minded people who share similar interests to that of yours.

One thing i noted was that almost all the people I talked to did TDD! We don’t do TDD here in favoritemedium and I feel may be… Just may be, we can try it out. Feel like I am in the stone age not doing TDD when everyone else is at the party rocking like a TDDstar!. Or may be its just that the projects and the client we get don’t really go together with TDD.

After-party

All of my coworkers missed the after party so i had to go there all alone. Discussed TDD, photography, politics, android and many more things with a lot friendly ruby folks and it was pretty nice. Although I don’t drink alcohol the soft drinks and ‘chicken-on-a-stick’ finger food kept me busy :)

All in all think it was a grate event. Can’t wait for the next one in 2013!

Setting Up FuseOverAmazon(s3fs) on Ubuntu 10.04

Published on:
Tags: s3, ubuntu

FuseOverAmazon(s3fs) lets you access your S3 buckets as a mounted file system on your OS. Recently i had to set it up on a Ubuntu 10.04 host to facilicate backup. However it will fail to compile properly on a 10.04 host due to some incompatible dependecies. So you need to manually install a newer version of fuse on Ubuntu 10.04 that s3fs supports. And here is how i did it.

[Installing Fuse]
1
2
3
4
5
sudo wget https://launchpad.net/ubuntu/+archive/primary/+files/fuse_2.8.4.orig.tar.gz
tar xzf fuse_2.8.4.orig.tar.gz
cd fuse-2.8.4/
sudo ./configure
sudo make && sudo make install
[Installing s3fs]
1
2
3
4
5
6
7
8
9
10
11
wget http://s3fs.googlecode.com/files/s3fs-1.61.tar.gz
tar xvzf s3fs-1.61.tar.gz
cd s3fs-1.61/
sudo apt-get install build-essential libfuse-dev fuse-utils
libcurl4-openssl-dev libxml2-dev mime-support
./configure --prefix=/usr
make
sudo make install
sudo vi /etc/passwd-s3fs
sudo chmod 640 /etc/passwd-s3fs
sudo s3fs server-backup /mnt/s3

Note that in the above code server-backup is the name of the Amazon S3 bucket. And the /etc/passwd-s3fs contains the nesseary autherization details. You can access these details form the settings menu to the top right in your AWS web console under Security Credentails. You should find the access key id and the secret access key under the “Access Keys” tab.

[/etc/passwd-s3fs]
1
ACCESS_KEY_ID:SECRET_ACCESS_KEY