04 January 2015

Development fixtures (what guides.rubyonrails.org refers to as ‘seed data’ ) tend to balloon and unDRY fairly quickly in a large application. Using FactoryGirl factories for fixtures can eliminate the clutter because you only need to specify model attributes when they need to diverge from your factory template defaults.
I decided to try this in a brand new Rails 4.1.5 app this week. After defining my ‘Post’ factory in spec/factories/post.rb, I encountered an error while adding

FactoryGirl.create(:post)


to seed.rb:

NoMethodError: undefined method `delete' for nil:NilClass
    from /Users/dev/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0/gems/activerecord-4.1.5/lib/active_record/attribute_methods/write.rb:81:in `write_attribute_with_type_cast'


Turns out I had overriden Post#initialize without calling ‘super’, so my Post instance never inherited a 'delete' method. FactoryGirl assumes the existence of a 'delete' method on ActiveRecord instances it tries to create. Hope this will save someone a few minutes of time, as the error message doesn’t obviously point to this issue.

Environment:

rails (4.1.5)
factory_girl_rails (4.5.0)


//

View Comments

10 February 2012

Last week I coded my own version of the New York Times' article slider panel in JS. Recently I have been using Chrome as my development browser; I switched over from Firefox a few months ago. After verifying that the slider worked correctly in Chrome, I was surprised to find that it did not work at all in Firefox. In fact, Firefox was not loading any of my external CSS or JS pages. Here is a look at the "head" element of my demo HTML page:

<head>
    <link rel="stylesheet" href="styles.css" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="X-UA-Compatible" content="chrome=1,IE=9" />
    <meta name="viewport"/>
    <script type="text/javascript" src="jq.js"></script> 
  </head>


Spot the problem? That's right, the first line does not have a "type" attribute. It should look like this:


<link rel="stylesheet" href="styles.css" type="text/css" />


Firefox 9.0 will not load external CSS or JS pages without the "type" attribute! Chrome 17.0, Safari 5.1, and IE 8 do not need the type attribute, so be sure to test in Firefox if you develop in any of these. //

View Comments

27 December 2011

I was moving a demo app from Heroku to Amazon recently when I decided at the last minute that I wanted to keep the demo data. I used Heroku's API to curl a postgres pg_dump to my desktop; directions are found here.


Unfortunately, the pg_dump file format is binary by default, so I couldn't simply peek inside to verify the backup. I decided to create a "peek" database for this purpose:

> psql 
psql > create database peek;


I then loaded the pg_dump file into this empty database for viewing:

> pg_restore -d peek heroku.bck


Postgres complained a lot during the load, but as you can see, the errors all dealt with the permissions mismatch between Heroku and my desktop. In fact, all of the data loaded correctly - I did not have to prepare a role or schema of any sort. Nice.

pg_restore: [archiver (db)] Error while PROCESSING TOC:
pg_restore: [archiver (db)] Error from TOC entry 1482; 1259 179323 TABLE admins kdhvssheeq
pg_restore: [archiver (db)] could not execute query: ERROR:  role "kdhvssheeq" does not exist
Command was: ALTER TABLE public.admins OWNER TO kdhvssheeq;
-- etc etc etc


If you know of a better way to do this, please let me know. This got the job done in a few minutes, and is easily scriptable if you want to verify backups through grep'ing column contents inside a postgres backup, for example. //

View Comments

12 November 2011

Here is a blow-by-blow list of commands I issued and errors I encountered/made while deploying a Rails 3.1 app to CentOS 6. I've found CentOS much easier to work with than Ubuntu for Ruby environments. Hope this is helpful for someone.

$root useradd USER 
# add USER to sudoer's file. I used this line: USER ALL=(ALL)       ALL
$root visudo 
$root su - USER


Install and start ssh server at login for ssh access:

$ sudo yum install openssh-server
$ sudo echo "/sbin/service sshd start" >> /etc/rc.d/rc.local 


Important libraries required by RVM, Ruby, and Git:

$ sudo yum install git gcc-c++ make patch zlib-devel openssl-devel readline-devel


Install RVM as single user:

$ bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )


Install VMWare Tools through the CentOS GUI (my server happens to be a VMWare VM):

$ rvm install 1.9.2


Install MySQL. After installation, use the 'mysql' and 'mysqladmin' commands to set up your MySQL users and databases:

$ sudo yum install mysql-server mysql mysql-devel
$ cd RAILS_PROJECT_DIR 

$ rake db:migrate RAILS_ENV=production
#=> Could not find a JavaScript runtime


Oops, I am used to OS X which comes with a JavaScript runtime. I installed Node.js for the V8 JS runtime. Go here for install instructions: http://nodejs.org. It should be as simple as ./configure ; make ; make install. The libraries below were Node dependencies:

$ sudo yum install python libssl-dev


Then:

$ cd RAILS_PROJECT_DIR
$ rake db:migrate RAILS_ENV=production
#=> success!


Install and set up Passenger:

$ sudo yum install curl-devel httpd-devel apr-devel apr-util-devel
$ gem install passenger
$ passenger-install-apache2-module


Passenger will ask you to add 8 or so lines to the Apache config file (I found my config file here: /etc/httpd/conf/httpd.conf). I've included lines I used below as an example:

LoadModule passenger_module /home/USER/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9/ext/apache2/mod_passenger.so
PassengerRoot /home/USER/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9
PassengerRuby /home/USER/.rvm/wrappers/ruby-1.9.2-p290/ruby

...

<VirtualHost *:80>
   ServerName localhost
   DocumentRoot /var/www/html/RAILS_PROJECT_DIR/public    
  <Directory /var/www/html/RAILS_PROJECT_DIR/public>
     AllowOverride all             
     Options -MultiViews
  </Directory>
</VirtualHost>


$ sudo apachectl -k start
#=> httpd: Syntax error on line 202 of /etc/httpd/conf/httpd.conf: Cannot load /home/USER/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9/ext/apache2/mod_passenger.so into server: /home/USER/.rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9/ext/apache2/mod_passenger.so: cannot open shared object file: Permission denied


After googling a bit, I found that many people blamed this issue on Selinux. Selinux is enabled by default in CentOS 6. Switching Selinux off fixed this problem. I should probably learn Selinux and create my own ruleset, but I wanted to get something running today.

$ sudo emacs /etc/selinux/config 
# set: SELINUX=disabled
$ su - USER # create a new login shell to be sure that Selinux options are refreshed
$ sestatus # confirm that Selinux is disabled
#=> SELinux status:   disabled

$ sudo apachectl -k start
#=> ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)


Oops, need to start MySQL:

$ service mysqld start

$ rake db:migrate RAILS_ENV=production
#=> success


At this point, your server should be serving your app. In my particular environment, I had add a firewall rule to iptables:

 ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http


You can check your firewall rules with this command:

$ iptables -L


Depending on how you like to manage your assets in Rails 3.1, you may see this error when hitting your app:


ActionView::Template::Error (application.css isn't precompiled)


I chose to precompile my assets:

$ rake assets:precompile
$ emacs RAILS_PROJECT_DIR/config/environments/production.rb #config.assets.compile = true


Feel free to add suggestions or other problems encountered in the comments! //

View Comments

12 October 2011

Do you sass that hoopy Ford Prefect? Now there's a frood who really knows where his towel is. - The Hitchiker's Guide to the Galaxy

The following three SASS snippets all compile to the same effective CSS (effective, not identical):

#left-col, #right-col { height: 900px; }
$col-width: 900px;
#left-col {
height: $col-width;
...
}
#right-col {
height: $col-width;
...
}
.col {
height: 900px;
}
#left-col {
@extend .col
...
}
#right-col {
@extend .col
...
}

Which form do you use? If my SASS file is very small, I prefer the CSS-style option 1. In practice, I end up using option 3 the most, since I tend to have large chunks of CSS code that I can abstract into a class.


I have yet to use SASS mixins.


Thank you SVN for this inspiring article: Taking Control of the Cascade. //

View Comments

14 September 2011

Jason Seifer has a pithy, informative rake tutorial here, but one thing that tripped me up when I was building custom rake tasks recently is that you need to explicitly load the Rails environment into your task; simply sticking a task in a .rake file in your Rails app tree is not sufficient.


For example, here is a simplified version of a rake task I wrote for Tweetful:

task :load do
tweets = Twitter.user_timeline("happythenewsad", :count => 199) tweets.each do |status|
Post.create! do |post|
post.creator = status.user.screen_name
post.content = status.text
end
end
end

This code will produce the following error when executed:

rake aborted! uninitialized constant Object::Post

Experienced Rails users will quickly infer that post.rb is probably not in the load path, which is the case. Here is one quick edit that causes the above code to execute in the Rails environment, which will probably default to "development":
task :load => :environment do . //

View Comments

12 September 2011

I pushed a Rails 3.1 app to Heroku for the first time today (plugsandwifi.com). It ran smoothly in development mode, but I got a nasty 500 error in production:

Completed 500 Internal Server Error in 75ms
2011-09-11T19:34:20+00:00 app[web.1]:
2011-09-11T19:34:20+00:00 app[web.1]: ActionView::Template::Error (logo.png isn't precompiled):

Logo.png is a simple image. Heroku attempts to precompile your assets (this is now a necessary step for whizzy things like sass and coffee script) if you haven't already as part of their one-step deploy process: http://devcenter.heroku.com/articles/rails31_heroku_cedar.


For some reason, the precompile process was failing for me, although Heroku's log should have acknowledged that issue when I deployed. To fix the problem I simply ran this command: RAILS_ENV=production bundle exec rake assets:precompile. I then git add'd the generated directory and deployed to Heroku. Note: For those following along with Heroku's instructions, Heroku did NOT acknowledge my pre-compiled assets in its printout. //

View Comments

23 August 2011

I learned a lot of great stuff at NYCSW last week, one thing being that I would be more effective in my space if I became a fluent - nay, native - writer of JavaScript. Chrome and Firefox have great JavaScript consoles, but I like "jsc" better - it starts directly from command line and comes packaged in OS X.


Ajaxian has a very helpful post about setting up jsc, but unfortunately the paths they use to set up the executable appear to be dated. I've verified that this is the default jsc executable path for both Snow Leopard and Lion:

/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc


I added jsc to my path with this command:

$ sudo ln /System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc /usr/local/bin/jsc

View Comments

17 August 2011

... was my weekend project for Startup Weekend - check it out. Right now it's in (public?) alpha and we have plans to continue hacking on it. Lots of fun working with the Foursquare API for the first time. Thanks for a great experience, P&W team!

View Comments

13 August 2011

This weekend I am at NYC Startup Weekend (#nyscw and @nycsw on Twitter), hacking out a product with a bunch of talented guys. More details to come. For to-the-minute updates, follow me at @happythenewsad.

View Comments

11 August 2011

In the bad old days of the World Wide Web, a simple mailto link was all you needed to supply a contact for a website. Time to step it up.


These days, lots of people use contact forms, like this one. Contact forms are great because:


1. For most modern browsers (Firefox, Chrome, etc.), mailto will open the default email client. Users tend to be irritated when an application does things they don't expect. For instance, I use Gmail for most of my email needs, but I have the Thunderbird email client installed and often running on my laptop. I don't appreciate having Thunderbird pop open an empty email template after I click something like: "Contact Us!." My Thunderbird email client maps to my personal email address, and I may not want to send email from my personal address in a business context.


2. Forms obfuscate the receiving email address. If a contact form forwards its message to an email address, it is much more difficult for that email address to be abused (i.e. spammed). Folks can't see it.


3. Forms add a layer of indirection, allowing you to inject additional business logic into the process. For example, you could send the form delivery job to a queuing service (example), taking load off of the web server and shielding the user from mail delivery delays. You could also react easily to architecture changes, like sending form data straight to a database instead of an email inbox - users won't notice in behavior.


4. Contact forms are good design. They allow you to present the user with a minimal amount of complexity. For example, my contact page only asks for a message and an email address - it does not ask for a title like a full-blown email would. A title is not necessary for a simple contact page and saves the user time and distraction. //

View Comments

04 August 2011

Installing Lion overtop of Snow Leopard on my development laptop has been pretty painless, with a few exceptions. One was Git - the path Git's executable was removed from bash (I didn't check other shells). This was easily solved by adding PATH=/usr/local/git/bin:$PATH to my bashrc.


Another issue was Xcode and the development tools (i.e. gcc) that it brings along. Something was wrong when Ruby gems with native extensions refused to compile:

> gem install nokogiri --no-ri --no-rdoc
Building native extensions. This could take a while...
ERROR: Error installing nokogiri:
ERROR: Failed to build gem native extension.

This line printed in the gemmake.out file:

checking for libxml/parser.h... *** extconf.rb failed ***

I tried downloading some 'usual suspect' libraries:

> brew install readline wget
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/
ruby/1.8/rubygems/
custom
require.rb:31: command not found: /usr/bin/xcode-select -print-path Warning: Xcode is not installed! Builds may fail!

Formula already installed: /usr/local/Cellar/readline/6.1

Xcode not installed? That was strange, since the Xcode 3.2.3 application started up fine through the GUI. I decided to move Xcode 3.2.3 to a temporary directory and install Xcode 4.1 from the App Store. Everything went smoothly. Xcode will detect an old version of Xcode and put it in a directory called "Developer-old" - see the image below. I recommend installing Xcode 4 if you run into similar problems; you shouldn't run into trouble. //



View Comments

27 July 2011

I've decided to use human-friendly urls (slugs) for my blog posts. I found the friendly_id gem very easy to use with Rails/ActiveRecord. Here are some of my dev notes:


The rails generate friendly_id command simply generates a migration that builds a "slugs" table:

peterkong 1.9.2@peter_blog >rails generate friendly_id
create db/migrate/20110719003359_create_slugs.rb

adding a line to Post.rb:

class Post < ActiveRecord::Base hasfriendlyid :name, :use_slug => true #########

in Rails console:

Post.create! do |post|
post.title = "my kingdom for a title!"
post.name = "petertechblog098"
post.content = "a quick brown fox"
end

<Post id: 202, name: "peter
techblog098", title: "my kingdom for a title!", content: "a quick brown fox", createdat: "2011-07-19 00:45:05", updatedat: "2011-07-19 00:45:05", creator: nil, cachedslug: "my-kingdom-for-a-title">

As you can see, friendlyid transforms your sluggable attribute - in this case "title" - into a URL-friendly string. Notice the original (!) is removed.


Your DB rows will still increment normally by id; they just will include the "sluggableid" attribute from now on. This makes friendlyid minimally invasive to your app - anything you were previously doing with id still works.


Friendlyid handles name collisions fairly well:

Post.create! do |post| post.title = "my kingdom for a title!" post.name = "petertechblog098" post.content = "a quick brown fox" end

=> http://localhost:3000/posts/my-kingdom-for-a-title--2

If you change the title, BOTH links still work:

http://localhost:3000/posts/my-kingdom-for-a-title--2
http://localhost:3000/posts/my-kingdom-for-a-title-updated

Another great thing about friendlyid is that it keeps your models at arm's length: no attributes in yours rows are modified; only the "cachedslug" attribute is added.


All slug info is contained in the Slug table:

Slug.findbysluggableid 204
=> #<Slug id: 5, name: "newest-post", sluggable
id: 204, sequence: 1, sluggabletype: "Post", scope: nil, createdat: "2011-07-19 01:23:45">
Hope that answers some questions you may have about friendly_id and friendly URLs in general. Enjoy!

View Comments

21 July 2011

This week I installed Disqus on my blog. I have set up Disqus such that the majority of the Disqus JavaScript code resides in my _post partial. However, I wanted that nice "View Comments" feature on my index view and only my index view (i.e., not in the "show" view).


Previously, I displayed my posts in the index view in a single line using the handy :collection option in Rails 3:


<%= #render :partial => 'post', :collection => @posts, :spacer_template => 'post_spacer' %>

This poses an issue though, because there is now no simple way that I know of to let Disqus interact with each of my posts using a unique identifier the way it wants to (I use slugs generated from the friendly_id gem as my unique identifier for Disqus). You see, the Disqus JavaScript inserts the "comment count" code with respect to links that contain an anchor called "disqus_thread", like so:

For the following link, Disqus will fetch the comment count by the identifier: article_1_identifier
<a href="http://example.com/article1.html#disqus_thr...d" data-disqus-identifier="article_1_identifier">First article</a>

(Look: http://docs.disqus.com/developers/universal/)


Okay, what about putting the #disqus_thread anchor in the spacer partial, like this?


<%= #render :partial => 'post', :collection => @posts, :spacer_template => 'post_spacer', :locals => {:post => post} %>

Unfortunately, :locals doesn't pass to the :spacer_template - I couldn't figure out if there was another way. The spacer template usually contains static data, not data fetched from the DB, which is what I need. I ended up reverting to an old fashioned loop to display my posts, for greater control:


posts#index.html.erb:
<% @posts.each do |post| %>
<%= render :partial => 'post', :locals => {:post => post } %> <a href="<%= post_url(post) + '#disqus_thr...d'%>">View Comments</a>
<% end %>

What do you think? Any feedback? On the plus side, I can eliminate the spacer partial here - one less file to worry about.

View Comments

19 July 2011

...great talk by IA Ventures on the business of big data. Key takeaways:


> "big data" is defined as 1) large 2) unstructured and 3) real time.

> successful big data companies (especially those with data driven products, like amazon) use their data to improve their products


Check the video. I wish I lived closer to General Assembly - I love everything they do.

View Comments

05 July 2011

I am a good software engineer. I am starting this blog because I want to become a master software engineer. I want to become a master software engineer because I want to launch/join a tech startup in the future. I decided to become an entrepreneur six months ago after reading this article by Paul Graham. I’ve worked as an employee in a few startups already:I was a food critic in Tokyo for my previous job (here is a post from my old food blog).


I built this blog system from scratch with Rails 3. It's not much now, but I intend to sharpen my UI/UX skills through developing it on a weekly basis. The problems I encounter and the solutions I discover will be the content of the blog. Thanks for reading!

View Comments


Ustreet


Peter Kong is a
software engineer.