July 19, 2010

10 Steps to Capistrano and Plesk Subdomains Deployment

Filed under: Designer Showcase, TDS Developer's Corner — Dawn @ 12:56 pm

We’ve adopted a standard convention for deploying Rails apps that places the files in a subdomain of our clients’ domains. Since we use Plesk, there are some steps we have to take to get Capistrano deploys working. Since we deploy a lot of apps, I decided to write this guide as much for the office as for anyone who may find it useful. Let’s go through the steps:

  1. Create your subdomain in Plesk (ie. myrailsapp)
  2. Navigate to the /domain.com/subdomains/myrailsapp/conf directory
  3. Create a vhost.conf file. Again, we use a convention that creates a new directory within /myrailsapp that holds our rails code. Fittingly, we name the directory /rails. The DocumentRoot points to the public directory of our application. Enter the following into the vhost.conf file:
  4. DocumentRoot /var/www/vhosts/domain.com/subdomains/myrailsapp/rails/current/public 
    RailsEnv production
    
    
  5. If you haven’t already installed the capistrano and capistrano-ext (for multistage environments such as testing and production deploys), you’ll need to get them. The Capistrano tutorials will walk you through that process.
  6. With the gems installed, now we want to capify our code. In your root rails app directory, enter the following command. (You may have to sudo the command depending on your directory permissions.)
  7. capify .
    

    This will create two files: Capfile and deploy.rb in your /config directory.

  8. Open up your deploy.rb file and enter your configuration variables. Again, you can refer to the Capistrano tutorials for help.
  9. If you are only planning to deploy to a single environment, you’re work is done. If you plan a multi-stage environment, you’ll want to set the stages in your deploy.rb file and require the capistrano-ext gem like this:
    set :stages, %w(testing, production)
    set :default_stage, "testing"
    require "capistrano/ext/multistage"
    
    
  10. Within the /config directory, create a new /deploy directory and two new files, testing.rb and production.rb. These files will provide the deploy details for each environment.
  11. Open up your new .rb files and enter the following for each environment:
    
    #############################################################
    #   Application
    #############################################################
    
    set :application, "myrailsapp"
    set :deploy_to, "/var/www/vhosts/domain.com/subdomains/myrailsapp/rails"
    
    #############################################################
    #   Settings
    #############################################################
    
    default_run_options[:pty] = true
    ssh_options[:forward_agent] = true
    set :use_sudo, true
    set :scm_verbose, true
    set :rails_env, "testing" 
    
    #############################################################
    #   Servers
    #############################################################
    
    set :user, "username"
    set :password, "user_password"
    set :domain, "myrailsapp.domain.com"
    server domain, :app, :web
    role :db, domain, :primary => true
    
    #############################################################
    #   Passenger
    #############################################################
    
    namespace :deploy do
      desc "Create the database yaml file"
      task :after_update_code do
        db_config = <<-EOF
        production:    
          adapter: mysql
          encoding: utf8
          username: database_username
          password: database_password
          database: database
          host: localhost
        EOF
        
        put db_config, "#{release_path}/config/database.yml"
    
      end
        
      # Restart passenger on deploy
      desc "Restarting mod_rails with restart.txt"
      task :restart, :roles => :app, :except => { :no_release => true } do
        run "touch #{current_path}/tmp/restart.txt"
      end
      
      [:start, :stop].each do |t|
        desc "#{t} task is a no-op with mod_rails"
        task t, :roles => :app do ; end
      end
      
    end
    
    
    Then add the details of your repository for either subversion or git.
    
    
    #############################################################
    #   GIT
    #############################################################
    
    set :scm, :git
    set :branch, "master"
    set :repository, "git@github.com:your_github_path/MYRAILSAPP.git"
    set :deploy_via, :remote_cache
    ssh_options[:forward_agent] = true
    
    #############################################################
    #   SVN
    #############################################################
    
    set :scm, :svn
    set :branch, "trunk"
    set :scm_user, 'username'
    set :scm_password, "user_password"
    set :repository, Proc.new { "--username #{scm_user} --password '#{scm_password}' --no-auth-cache http://doman.com/path/to/your/subversion/repository/#{application}/trunk" } 
    
    set :deploy_via, :remote_cache
    ssh_options[:forward_agent] = true
    
    
  12. That’s it; you’re ready to deploy. Back at your terminal window, you’ll type the respective environment to which you’re deploy:
cap testing deploy

A final note: make sure the user specified in your deploy files has permission to create directories on the server, otherwise your /releases directories will not be created.

Feel free to ask any questions if you’re having trouble with your Plesk subdomain and Capistrano deployment. Good luck!

January 7, 2010

Rails validation error not displaying - validates_presence_of, error_message_for

Filed under: TDS Developer's Corner — Dawn @ 4:26 pm

I hit a wall recently as I tried to track down the reason validates_presence_of was not displaying errors. Rails validations normally go off without a hitch, so I was a bit stumped when my attempts to save blank fields were not triggering the appropriate messages. After ensuring my model and view were correct, I fired up the console to make sure my validations were working in the first place. After loading an object and attempting a save, I checked to see if the errors object returned false. Sure enough, all of the validations were enforced.


>> @contact = Contact.find_by_id(9)
=> #
>> @contact.save
=> false
>> @contact.errors.empty?
=> false
>> @contact.errors.count
=> 6
>> @contact.errors.each_full { |msg| puts msg }
   City No blanks
   Zip No blanks
   First name No blanks
   Address No blanks
   Last name No blanks
   State No blanks

After more head banging, I was ready to give up with a simple notification workaround on the update method.


if !@contact.errors.empty?
  flash[:error] = "You are missing required fields."
  redirect_to edit_contact_url(@contact.user)
else
  flash[:notice] = "Successfully saved."
  redirect_to contact_url(@contact.user)
end

That works, but it doesn’t take advantage of the Rails’ error_messages_for helper to display helpful messages and highlight problem fields. Then I realized the initial error. During redirects, the object’s data isn’t passed, so while the validations were enforced (the form data would not save upon submission), no errors were being output to the screen. My new code rendered the page along with the error messages:


if !@contact.errors.empty?
  render :action => 'edit'
else
  flash[:notice] = "Successfully saved."
  redirect_to contact_url(@contact.user)
end

May 11, 2009

RailsConf Retrospectives, Part 1: Testing

Filed under: TDS Developer's Corner — gary @ 1:27 pm

The Thunder Data dev team was represented at this year’s RailsConf in Las Vegas, and we learned quite a bit.  We’re starting a series of RailsConf Retrospectives to delve into some of the topics covered at the conference.

Testing

One of the most pervasive themes at RailsConf was that of testing and Test-Driven Design, principles that have been embraced in the Rails community for good reason.  When done properly, TDD yields a suite of automated tests that can be run at any time to ensure the integrity and production readiness of an application.  But what exactly is testing, and how does it yield such boons?

Red-Green-Refactor

The essence of TDD is the cycle of Red-Green-Refactor.  Start by writing a high-level test describing a bit of functionality that fails, write code until it passes, and then clean up and improve the code.  This continuous cycle results in not only cleaner, more robust code, but by its very nature produces a set of tests that describe the entire functionality and operation of the application as a whole.  This process also forces tests to be written and debugged first, so that any errors later can be properly attributed to the application code, not the tests.  At the end, you will have a test suite that both defines and monitors the functionality of the application.

Fixing It Up

What happens when it comes time to rewrite that particularly nasty controller?  With TDD, have no fear!  If an application has a good set of tests, refactoring is a snap.  Simply make whatever changes you need and rerun the test suite.  If everything comes back green, you may proceed.  If not, track down the failing tests and fix the application code that is causing failure.  Over the lifespan of an application, a comprehensive set of tests for general use and edge cases alike will allow for any future development on any particular part to proceed without a hitch.

Stay tuned for more articles as we continue our RailsConf Retrospectives series.

March 13, 2009

Show Something Useful

Filed under: TDS Developer's Corner — gary @ 5:30 pm

As a developer, it’s easy to get buried in code and forget how people actually use what I’m writing.  An interface element or workflow that seems intuitive to me can often lead to confusion and frustration in the casual visitor.  If I want to transform my code into an application, I must become the visitor and walk the path I’ve built.  Each step must answer one question: Am I showing something useful?

Answering this question is a powerful way of evaluating any design.  Too often, it’s easier to display some sort of bland, generic page that does nothing of value.  Each of these non-pages cost us visitors who would rather spend time doing something useful instead of aimlessly wandering, looking for the next step.  All the visual gimmicks and traffic-generating tricks in the world are for naught if I can’t say “Yes, I am showing something useful.”

March 6, 2009

Catch-all Routes in Rails

Filed under: TDS Developer's Corner — Nick @ 1:47 pm

On one of our projects we were porting over a legacy application written in PHP to Rails. A lot of the application’s users accessed the site with bookmarked pages. So we wanted to redirect users when we saw specific words like “buy” or “.php”, so customers were not left staring at a 404 page.

To accomplish this we simply added a “catch-all” route in Rails. This allowed us to inspect the path and take action based on some kind of business logic. Below is the code added to the end of the routes.rb file:

map.connect ‘*path’, :controller => ‘redirect’, :action => ‘index’

This will redirect any requests that are not matched in the routes files to the redirect controller’s index action. In that method we can then define logic on how we want to handle the request. We can even perform actions with the database, since we’re inside a controller at this stage. In our case we simply used a regular expression to evaluate the URI:

def index if request.request_uri =~ /buy|.php/ redirect_to “/” else render :file => “#{RAILS_ROOT}/public/404.html”, :status => 404 end end

It’s a simple, yet powerful little technique for handling URLs dynamically.

December 19, 2008

Use CSS to Mark Fields as Required

Filed under: TDS Developer's Corner — Nick @ 5:17 pm

Curious on how the pros handle marking required fields on their forms?  Wonder no more!  Below I’ll describe a technique I employ on my own forms to make marking required fields a simple and straight-forward process.  I will assume you have at least a basic working understanding of CSS, but even if you do not you should be able to still employ this technique.

First lets start with the HTML:

<ol>
<li class="required">
<label for="item1">Item One</label>
<input name="item1" id="item1" value="" />
</li>
<li>
<label for="item2">Item Two</label>
<input name="item2" id="item2" value="" />
</li>
<li class="required">
<label for="item3">Item Three</label>
<input name="item3" id="item3" value="" />
</li>
<li>
<label for="item4">Item Four</label>
<input name="item4" id="item4" value="" />
</li>
</ol>

This is a standard ordered list.  You may be curious why I choose to wrap my form elements inside a list?  It’s a recommended best practice, as is the use of the for attribute in the label.  If you want to learn more you can google for “form fields li best practices” to read the opinions out there.

Now to style our two required fields with *’s is a simple matter of some CSS code.  Our goal is to not actually use text in the html itself.  The reason we don’t want to do this is that “required” is not really content, it’s meta-information.  Marking a field as required or not therefore is something that should be treated as a style, not content.

If a client came back and asked to have the mark for required fields be treated differently, say instead of a * (star) they wanted an ! (bang), we only have to edit one little line of code.  What if they didn’t want a mark at all but instead wanted to have it highlighted with a red box?  You start to see the wisdom in handling this through a style than in the html itself.  We’ll need just a handful of styles to accomplish our goal:

 ol { list-style: none; }
li.required:after {
content: "*";
font-size: 18pt;
margin-left: -5px;
}
label {
display: block;
font-size: 14pt;
align: right;
margin-right: 0.5em;
}
input {
margin: 5px;
font-size: 14pt;
}

The :after pseudo-selector on the li element is a special selector for a marker.  You can think of a marker as a sub-element of the primary element that appears before or after it (in this case the li element with the class of required).  We could also select the marker that appears before using :before.  The resulting web page will look as below:

November 24, 2008

Testing, shmesting, who needs it?

Filed under: TDS Developer's Corner — Paul @ 6:03 pm

Now that I’ve been here for a couple months, I guess it is time to post a blog, but about what? Since, in large part, testing is new to me, (and an important part of developing Thundertix) I thought I’d start there. So read on if you want to hear about my experience. It’s been a wild ride.

Auto testing your code is a sexy idea to any programmer who has asked themself - ‘does my code work?’ Most importantly, ‘will it work when I move it to production’. Most of the time, the answer is “I think so, let’s see”. So testing, in theory, should allow you to forgo that nerve racking question altogether.

But testing, in my experience, is hard. More difficult than writing the code to begin with. By a long way. Not only because you are learning new constructs to exercise, poke and prod your app but also because you have to think differently about how your code is structured. Is the code in the right place - is it simple enough? Should I be moving my code out of the controller and into the model, as many of the best Rails programmers suggest? (When you start testing complex controllers, I can tell you, the answer is YES!)

So far, testing for me is like taking vitamins - it’s good for you - but may not taste good. So I tell myself, “every test makes your code stronger”. It’s a bit like exercising. The more tests you have the stronger your code will be. And you will know it - especially when you have to make sweeping changes.

I’ve got a long ways to go before I can say for sure that my code will work but, as I learn and get better, I can see the light at the end of the tunnel.

But, at the end of the day, if I never have to ask “Will my code work when I move it to production?”, it’ll all be worth it.

October 27, 2008

Feeling Lucky

Filed under: TDS Developer's Corner — Dawn @ 8:35 pm

Nicholas writes clean, elegant code.  Paul contributes beautifully to interface interaction.  Scott is a master of programming languages, and Manish and Manasi possess an enviable stick-to-itiveness attitude.  Then there’s me.

Fumbling as I am in learning Rails and attempting to pick up Scott’s reigns, I realize that I have been very fortunate in my reliance on great programmers.  So, if I haven’t said it to the guys and gals around me worthy of the title “programmer”, let me say it now, “My hat’s off to you!”

March 20, 2007

no left turn

Filed under: TDS Developer's Corner — PerlPilot @ 12:02 am

Today was an interesting day for debugging.

We’ve developed a flash application for a client that didn’t quite work right in IE6. Today the client called and said this is really going to be a problem as most of the people who will be using the application haven’t upgraded to IE7 and don’t use Firefox (hence they use IE6). So I spent some time trying to track down the problem.

I’d looked at it this before and couldn’t figure it out, so this time I put on my Stubborn Hat and dug in. I knew I had a “screen shot” that worked fine in IE6 while the actual application did not. So the first thing I did was make a static document of the HTML generated by the app. Now what? Should I gradually make the “screen shot” look like the application until the Flash bit stopped working? Or should I gradually change the application’s HTML until the Flash bit suddenly started working? Either way it was going to be a long tedious process. For no conscious reason other than “my gut told me to”, I chose the latter.

Actually, at first I thought it must be some quirk of how IE6 deals with javascript since that’s how we interface with Flash. But after a few minutes exploring that idea, I realized that the “screen shot” and the actual application would have the same quirks as the javascript parts were virtually identical. So, I started in on munging the non-javascript parts of the HTML. After quite a while of carefully removing bits of HTML and not getting the Flash portion of the application to do much of anything I was beginning to despair that I’d picked the wrong strategy. It didn’t seem that I was making any headway against the problem. I’d remove a small div and reload the page, remove a table tag and reload the page, etc. Nothing seemed to make a difference (but on the plus side, I had a much smalled document to deal with :-) Then … finally the Flash app worked in IE6!

And what, pray tell, was the problem? The application had a div tag with an id of ‘left’. Change the id to anything else and the Flash parts work as expected.

March 21, 2006

Web Search API from Y!, Google and MSN

Filed under: TDS Developer's Corner — Manasi @ 8:23 pm

Today, I was working on Web Search API provided by Google, Yahoo and MSN too. Developer’s life is so easy by these kind of API’s.

Still, I am looking for PHP serealized output from Google and MSN api’s, as Y! did for me :-)

I will update if I get any further information on this.