Thursday, June 30, 2011

undefined method `hash_for_... Solved.

Ever get a nasty error like this?
And I am on the controls page                        # features/step_definitions/web_steps.rb:44
      undefined method `hash_for_new_admin_organization_path' for # (ActionView::Template::Error)
      /Users/daze/.rvm/gems/ruby-1.9.2-p180@rails31/gems/actionpack-3.1.0.rc4/lib/action_dispatch/routing/polymorphic_routes.rb:133:in `polymorphic_url'
      /Users/daze/.rvm/gems/ruby-1.9.2-p180@rails31/gems/actionpack-3.1.0.rc4/lib/action_dispatch/routing/polymorphic_routes.rb:140:in `polymorphic_path'
      /Users/daze/.rvm/gems/ruby-1.9.2-p180@rails31/gems/actionpack-3.1.0.rc4/lib/action_view/helpers/url_helper.rb:111:in `url_for'
      /Users/daze/.rvm/gems/ruby-1.9.2-p180@rails31/gems/actionpack-3.1.0.rc4/lib/action_view/helpers/url_helper.rb:242:in `link_to'
      ./app/views/admin/organizations/index.html.erb:4:in `_app_views_admin_organizations_index_html_erb___2726815532635892939_2153996520'
No worries.  You probably just forgot something in your routes.rb file.
In my case, I had
<%= link_to "New Organization", new_admin_organization_path %>
in my view.  Sure enough, I hadn't specified the new admin organization path in my routes file.

Solution: put the following in my routes file:
namespace :admin do
  resources :organizations
end
If you find this helpful, feel free to comment below :].

Wednesday, June 29, 2011

Vacillating - just choose one

vacillate - verb (used without object): to waver in mind or opinion; be indecisive or irresolute

A few personal traits I want to improve on:
-patience
-making up my mind quickly

About the second one - it's important to have the mentality of just choose one! for the sake of productivity. Really... think about the cost of vacillating, of being uncertain. It eats up time better spent with something else, and it's especially bad if the issue is insignificant.

Here's one example (beware: 99% of you won't know what I'm talking about): choose Webrat or Capybara. They're both testing frameworks for Ruby on Rails, and I ended up choosing Capybara because (1) it has ongoing support and (2) whoever I asked seemed to be using it. There, done and done. Even if I had gone the other way, it's no big deal.

Okay, if that example flew over your head, then think about day-to-day things. Here's one: Which homework do I do first? If you're a high school student staring blankly at assignments crudely jotted down in your planner, wondering where to start, just choose one! In the end, you're going to do them all anyway (right?), so it's inconsequential where you start. The impact is just... nil.

So you probably get the idea that I appreciate maximum efficiency. Very true.
I really strive to make my time as productive as possible - which, actually, might tie to my patience threshold...

Tuesday, June 28, 2011

Authlogic steaming issue in Rails 3.1

At the moment, there's a streaming issue with Authlogic and Rails 3.1:
https://github.com/binarylogic/authlogic/issues/262#issuecomment-1460466

Apparently, Authlogic violates MVC in some entrenched way, and consequently this gem breaks Rails 3.1's new streaming.  Hopefully there will be a solution soon, but for now, if you get a

"Cannot modify cookies because it was closed. This means it was already streamed back to the client or converted to HTTP headers. (ActionDispatch::ClosedError)"

 (as I did when I run my cucumber tests together), you'll have to make do and e.g. run your cucumber tests independently by using tags (example: cucumber -t @authlogic-one).

(.+) and ([^"]*) - Regexps

The Cucumber testing framework of Rails generates "([^"]*)" if you have an undefined step like
Given a user named "John"
But you can also use "(.+)" or if you don't want the quotes, simply (.+).  Basically, (.+) and ([^"]*) are equivalent.

Misc. Tags: regexp, regular expression

Monday, June 27, 2011

Using MySQL as your development database

On my Mac OS X, I'm starting a new project with Rails 3.1, and I'm using MySQL as my development database because when I deploy, MySQL will be the production database, and the two dbs really should match.

Unfortunately, after running
rails new mynewapp -d=mysql
and testing out
rails server
I got this error:
error: 'Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)'
Of course I hadn't (1) started the MySQL server yet and (2) created my development database. This was new to me since I normally just developed with the sqlite db Rails automatically ships with for development.

After using homebrew to install mysql ("brew install mysql" as Ryan Bigg suggests at http://ryanbigg.com/2011/06/mac-os-x-ruby-rvm-rails-and-you/), I followed the added installation instructions that come with the brew install (viewable through "brew info mysql"
- pretty darn important to finish the mysql install with homebrew), and then ran these commands:

# start the server - something I'm not used to after using sqlite
mysql.server start
# create the db; specify -p if necessary
mysqladmin -u root create mynewapp_development

Then, "rails server" was successful.

(Note: running "mysql.server start" won't be necessary if you follow the instructions from "brew info mysql" and configure the start server on startup)

Friday, June 17, 2011

Speed test: rake vs. rspec spec, rake cucumber vs cucumber

I timed different rspec commands to see which ran faster.

These tests were done on a really old machine so the times would be drawn out.
Newer machines execute far quicker with negligible difference.

(Precondition: all tests run with regard to the same code.)

Test 1: rake spec:controllers vs. rspec spec/controllers
Results:
rake spec:controllers --> 23 seconds
rspec spec/controllers --> 15 seconds

Test 2: rake spec:models vs. rspec spec/models
Results:
rake spec:models --> 34 seconds
rspec spec/models --> 16 seconds

Test 3: rake spec:views vs. rspec spec/views
Results:
rake spec:views --> 20 seconds
rspec spec/views --> 11 seconds

Test 4: rake spec vs. rspec spec
Results:
rake spec --> 20 seconds
rspec spec --> 11 seconds

Conclusion: It is faster to use "rspec spec/..." than the broader "rake spec" command.

This makes sense because the rake command has to invoke the Rakefile first, and from what I've seen online, "rake spec" and "rake cucumber" also invoke "rake db:test:prepare" behind the scenes first - a necessary command to restore the test database from scratch if you blew away the old one.

Here's one more test I did - this time, with cucumber:

Test 5: cucumber vs. rake cucumber
Results:
rake cucumber --> 30 seconds
cucumber --> 21 seconds

Yep.

Tuesday, June 14, 2011

Capybara (click_link, JS problem) & Logging in directly with Authlogic

The click_link / JS problem
I'm using capybara, and I recently came across this error:
Given I am on the home page                              # features/step_definitions/web_steps.rb:42
And I am the registered poster "John Doe"                # features/step_definitions/user_steps.rb:1
When I log in                                            # features/step_definitions/user_steps.rb:11
      You have a nil object when you didn't expect it!
      You might have expected an instance of Array.
      The error occurred while evaluating nil.[] (NoMethodError)
      (eval):2:in `click_link'
      ./features/step_definitions/user_steps.rb:12:in `/^I log in$/'
      features/users_have_basic_abilities.feature:10:in `When I log in'
This was my step definition:

When /^I log in$/ do
  click_link "Login"
end

This is the kind of error that arises if the link you want to click has href="javascript:void(0)".  In my case, my link was

<a href="javascript:void(0)" id="login_activator">Login</a>

With the help of jQuery, this link toggles a div for the login form, but there is no easy way to test this with Capybara because Capybara uses RackTest, which doesn't execute JS.

My solution: avoid the complications of this JS testing (I'm positive it works anyway), and instead forcibly create user session to login.  After all, that's the whole point of this logging in thing - it should be preliminary for what I really want to test.

Logging in directly with Authlogic
I am using Authlogic (https://github.com/binarylogic/authlogic) for user validation.
While trying code like UserSession.create!(:login => etc., :password => "some_password" ...), I came across this error:
You must activate the Authlogic::Session::Base.controller with a controller object before creating objects (Authlogic::Session::Activation::NotActivatedError)
The solution: ensure the following code is executed before such a user session creation:

Authlogic::Session::Base.controller = Authlogic::ControllerAdapters::RailsAdapter.new(self)

Yep.
Unfortunately, in the end even there still were problems with the "save" method no longer working - something about the improper number of arguments.
So, my FINAL solution was that I had to use the Cucumber steps of navigating to some page, filling in the login form, clicking the button, etc.  I guess there never really was a good solution to all of this, so I recommend against using the type of link I did above (a link that opens a little form on the page).

Monday, June 13, 2011

The importance of specifying gem versions in your Gemfile

I'm starting to integrate cucumber into a Rails 3 application.  Specifically, I added 'cucumber-rails' to my Gemfile, but I kept getting this error when I ran "rake cucumber":
undefined method `click' for class `Capybara::Driver::RackTest::Node' (NameError)
Turns out it is very important to specify gem versions in your Gemfile.  I hadn't specified a version for cucumber-rails, so consequently, abstruse incompatibilities emerged.

All I had to do was change gem 'cucumber-rails' to gem 'cucumber-rails', '>= 0.5.1'

This is what my Gemfile currently looks like:

source 'http://rubygems.org'
gem 'rails', '3.0.3'
gem 'authlogic', :git => "git://github.com/radar/authlogic.git"
gem 'cancan'
gem 'paperclip', :git => "git://github.com/thoughtbot/paperclip.git"
gem 'acts_as_list', :git => "https://github.com/haihappen/acts_as_list.git"
gem "will_paginate", "~> 3.0.pre2"
gem 'dynamic_form'
gem 'mysql2'
gem 'nokogiri'
gem 'capistrano' # we deploy with capistrano

group :development, :test do
 gem 'sqlite3-ruby', :require => 'sqlite3'
 gem 'shoulda'
 gem 'cucumber-rails', '>= 0.5.1' # important to specify this version
 gem 'database_cleaner'
 gem 'capybara'
 gem "rspec-rails", ">= 2.0.0"
end

# These typically shouldn't be for production, but I need it for seed data
gem 'factory_girl_rails'
gem 'forgery'

*Also, it's important to re-run rails generate cucumber:install after a change related to cucumber in your Gemfile.

Sunday, June 12, 2011

Awards. Superficial?

Society has a clever way of motivating people. It has this concept called the "award," and it dates back to ages ago (because the Greeks and Romans certainly held contests and rewarded winners).

But have you ever saw through the whole affair? Have you ever gotten tired of them? Casting aside all pretension, I've gone to many, and over the years, they have become dry and dull. Yes, awards are great, but maybe the countless times I've sensed unjustness have led me to simply grow bored of them. People do not necessarily win things deservingly. For many awards, voting is a large factor and by consequence popularity as well.

Even, in my case, when I claimed the top through legitimate hard work, as I did in a few math contests, I gradually gained a feeling of "who cares?" It's all part of society's game to improve you.... which is of course good and noble and blablabla but the entire affair of praise, fame, etc. taints all value. Even when I won, I found myself shrugging with a mild grin on my face.

I've really come to treasure intrinsic value. This is when I feel real accomplishment. Think of the people who invented the internet. Oh, that's right, you CAN'T. It's not even clear to me who invented the internet... yet this invention is clearly one of the momentous in human history. The internet is responsible for millions of businesses, for creativity to outlet in infinite forms, for connecting society in a whole new way. Yet we don't know who the inventors of the internet are. Sure, go ahead, Google the answer. You'll come across a name, or several, but the fact of the matter is you probably didn't know these people before. Fame and praise had alluded them... but the intrinsic value of their achievement is paramount.

Friday, June 10, 2011

Who cares?

Hey, you're reading this. Maybe. But do I care what you think? Do you care what I think of you?

This past year, I've developed a quasi-nihilistic view of society. It probably has something to do with the college admission process, as I am currently wrapping up my senior year of high school.

It boils down to this: Does anyone really care? Okay, I'm not pessimistic (really - I'm actually very optimistic, and I can back it up with this incredible Time magazine article), but let's consider a few of the superficialities of American society, the ephemeral moments of praise and prestige that people get. Think of the compliments you get from classmates whom you don't really know that well, the congrats you hear given to others for winning Award X. It's mostly out of respect, isn't it? Or just for the fun of yelling something? When you really think about it, with regard to success, people primarily care about themselves and others' perception of themselves.
(disclaimer: this omits philanthropic caring. Also, I would like to re-emphasize the with regard to success)

This whole idea relates to something else you might find interesting: childhood behavior. See, I have a five-year-old sister, and I've observed quite the number of interesting things about certain behavior - behavior that epitomizes that of all children. I'm only going to focus on the one that is relevant here, and that is the sheer outrage of being explained something or told to do something that the child already knows about. Haven't you seen a kid just heat up in fury because someone older reminds the kid to wash his hands or do something he was going to do anyway? Part of this rage comes from the kid's desire to be seen by others as one who already knows, one who's more mature. He really cares about what others think - to the point that it pains him that anyone reminding him something could suggest he didn't know about it. Phrased differently, he recognizes extrinsic value, not intrinsic value. And, interestingly, as we mature, we develop a stronger sense of intrinsic value, a profounder feeling of value in that something simply exists, even if no one recognizes it.

In my experience, when it comes to success, society seems to blow up truthfully minor things. Society's praise becomes excessive, and meanwhile, deep down, no one really cares... people deep down focus on themselves.

(A little more rambling: what IS society, anyway? It's not any one person, though one person could very well contribute to this entity we call society...)

Sunday, June 5, 2011

"I love you." (Maybe?)

At least in the part of American society I've grown up in...

Why is it so common to say, "I love you," to all friends alike?  Doesn't this stifle the original power of the words?  More importantly, doesn't it make it harder to tell if someone is serious?

Thursday, June 2, 2011

Quick SQL command... those annoying quotes

Never ever forget the importance of details.

Here's an example of why.

I wanted to drop the "default" setting for a column of type string.  Rails' typical migrations do not have a convenient way of doing this, so I had to run an SQL command.
I admit that I at the time was not experienced with SQL.  Nonetheless I went to http://api.rubyonrails.org/classes/ActiveRecord/Migration.html to find the answer.  I found this:

Instead of copying and pasting and then editing appropriately, I typed it out... and failed to notice the appearance of the single-quotes.  It's really better to just copy and paste so the tiniest details are taken care of... in this case, typing in ' does not work; you have to use `.

I really wish I had scrutinized every single character - particularly any quotes.  It would have saved me quite some time.

The end result:
execute "ALTER TABLE `free_spaces` ALTER COLUMN `content` DROP DEFAULT"