Showing posts with label heroku. Show all posts
Showing posts with label heroku. Show all posts

Monday, September 13, 2010

Snippet Highlighting with Ramaze and Sequel

A few days ago I saw this post on creating a pastie "clone" using Sinatra and Datamapper. I thought that it might be cool to try something similar in Ramaze and Sequel. It actually ended up being pretty easy (and similar to the other post (especially since I "stole" most of his CSS, etc.)), so I thought I'd share it here. If you've read much of this blog, then you should be pretty familiar with most of this, so I won't go through all of the code here but just hit the highlights. Here's the controller, controller/main.rb:


# controllers/main.rb
#
# The MainController has methods for index/main (to create a new snippet) and show (to show
# an existing snippet).

# Require syntaxi for syntax highlighting.
require 'syntaxi'
Syntaxi::line_number_method = 'floating'
Syntaxi::wrap_enabled = false
Syntaxi::wrap_at_column = 120

class MainController < Controller

# The main/index page that shows a text area where we can put in a
# title and a snippet. We'll grab the title and snippet text, create a new
# snippet, and then go to the snippet display page to see it.
def index
@title = "Snippet!"

# We've got a post, so grab the title and the snippet and then create
# a new Snippet with them and the current time. We'll then go ahead and
# redirect to the show method with the id that we get from the snippet.
if request.post?
title = request[:title]
snippet_text = request[:snippet]
snippet = Snippet.create(:title => title, :body => snippet_text, :created_at => Time.now)
redirect rs(:show, snippet.id)
end
end

# The show page that shows an existing snippet. It takes the id of an existing
# snippet and if it exists shows it nicely highlighted. If it doesn't exist, we'll
# just go back to the main page after setting the flash.
def show(id)
@title = "Show Snippet!"

# Find the snippet if it exists
@snippet = Snippet[id]

if @snippet != nil
# Get some text we can use to substitute for the "[/code]" text so that it doesn't
# mess up Syntaxi.
replacer = Time.now.strftime('[code-%d]')

# Do the syntax highlighting of the text with Syntaxi after we've done our
# substitution.
@snippet_highlight = Syntaxi.new("[code lang='ruby']#{@snippet.body.gsub('[/code]', replacer)}[/code]").process

# Substitute the '[/code]' back in for our replacement text.
@snippet_highlight = "#{@snippet_highlight.gsub(replacer, '[/code]')}"
else
# The snippet doesn't exist, so set a message and just redirect
# to the main/index page.
flash[:message] = "Snippet #{id} not found."
redirect rs :index
end
end
end



We start out requiring syntaxi which can be used with a sudo gem install syntaxi. The next three lines set a few variables which can be read about at the link. The index method will all the user to put in a snippet in a text area and then we'll create the Snippet (see model/models.rb and dbMigration/001_RamazeSnippet.rb for the information in this table/model). After we've created the new snippet, we'll redirect to the show method with the id of the new snippet.

The show method takes the id of the snippet and then displays the syntax highlighted version of it. It grabs the snippet from the database and if the snippet is not nil, it creates a "replacer" for [/code] which signals syntaxi to quit highlighting. We then substitute this replacer for the a [/code] and process the snippet. When this is complete, we resubstitute the [/code] for replacer and save it so the view can get to it. The view/show.xhtml is pretty simple and just displays the title, the highlighted snippet, and the creation date.

Like I said, not too much other than the syntax highlighting that we haven't seen before here. You can check all of the code on GitHub and run the code on Heroku.

Let me know if you have questions.

Thursday, September 2, 2010

Sequel and Heroku

Well, this turned out to be a bit harder than I expected, but with quite a bit of help from the Sequel, Ramaze, and Heroku lists, I got it worked out. The source code for this particular exercise is here. I'm only going to show a couple of files here as everything else you've already seen. First, here's how to do the migration in a rakefile ...


namespace :db do
require 'rubygems'
require 'sequel'
Sequel.extension :migration

task :migrate do
m = Sequel::Migrator
db = Sequel.connect(ENV['DATABASE_URL'] || 'sqlite://library.sqlite')
dir = "dbMigration"

target = ENV['TARGET'] ? ENV['TARGET'].to_i : nil
current = ENV['CURRENT'] ? ENV['CURRENT'].to_i : nil

m.run(db, dir, :target => target, :current => current)
end
end


We create a sequel migrator and connect to the database. The database connection line contains two parts. The first side is if there's an environment variable named DATABASE_URL then we'll use that to connect to the database. This is an environment variable set by Heroku. If this isn't set, then we'll go ahead and connect to a sqlite database, library.sqlite. We use the Sequel.connect command rather than Sequel.sqlite as we don't know which type of database we're going to be using. On Heroku, it will be PostgreSQL and locally, we use sqlite. Next up, we set the directory where we'll keep our migrations, in this case, dbMigration which is my standard. After that, there's two lines used for telling sequel which version we're going to, target, and starting from, current. Finally, we run the migrator with the database, directory, target and current. The final two are part of a hashtable that's used by this migrator. You could also use m.apply where the first two parameters are the same and then pass the target and current as integers, but the migrator code seems to imply that the run version is preferred. To run this locally, simply do a rake db:migrate and it should migrate to the latest version. To move to a different version you can run rake TARGET=0 db:migrate to remove everything from the database. If you just want to move to the latest version, don't put a target or current in, they'll be nil, and it should just migrate to the latest. Now, to run it on Heroku and migrate the database there simply add heroku in front of the command as in heroku rake db:migrate after you've pushed all the code up to Heroku with a git push heroku master as we saw in the last post.

I haven't talked about rake before, so I should probably give a little background for it. It's a ruby version of the Unix make. It has tasks and commands to do them. The homepage for it is here and here is a nice article on using it.

OK, now let's take a look at our model file model/models.rb.


# The database should have been set up using the database migrations in
# the dbMigration directory.
require 'rubygems'
require 'ramaze'
require 'sequel'

# Open the library's database. This must be done before we access the models
# that use it.
Sequel.connect(ENV['DATABASE_URL'] || 'sqlite://library.sqlite')

#
# This is the model for the authors and is backed by the :authors table in the
# database.
#
# Create the Author model.
class Author < Sequel::Model
many_to_many :books
end

#
# This is the model for the book and is backed by the :book table in the
# database.
#
# Create the Book model.
class Book < Sequel::Model
many_to_many :authors
end


This looks exactly like our previous models with a couple of exceptions. Here, we've moved our database connection into here from start.rb. It probably makes more sense here and keeps all of our Sequel code in one place (I got this idea from the Ramaze generated code). The connection itself looks surprisingly like our connection that was used in the rakefile. We end up using either a DATABASE_URL environment variable (supplied by Heroku) or the sqlite library.sqlite. After that, there are a couple of models that are in the database that we can use. The tables for the database and some data are created in the dbMigration/001_LibraryMigration.rb file.

You can see the end result of all of this here.

All of the code for this is up on github and as always, if you have questions, leave them in the comments.

Friday, August 13, 2010

Ramaze, GitHub, and Heroku

I first heard of Heroku from, I believe, a rant by Zed (if you're offended by profanity, this is probably not for you). It looked pretty interesting and so I decided to give it a try. This was actually a bit more involved than I thought, not hard, but for the first time you have more than a few steps to get through. What I'm going to show is how to a) get Git running, set up GitHub, create the Ramaze application, load it to GitHub, and finally load it to Heroku. Strictly speaking, you don't need GitHub to get the app running on Heroku, but I'm going to start putting some of my posts up there and so I thought I might as well show it too.

Let's start with getting git up and running. On my Ubuntu system, simply type sudo apt-get install git-core. After that type git --version (my shows git version 1.7.2.1) to make sure everything installed correctly.

Next, let's set up a GitHub account. Go to http://github.com/plans and create yourself a free account (or move up to a paid account if you want). Next, you're going to need to generate a SSH key which will be used by both GitHub and Heroku. You can go to http://help.github.com/linux-key-setup/ if you're running Linux or http://help.github.com/windows-key-setup/ if you're on Windows (probably similar for you Mac users). Follow the directions and you should now have access to your GitHub account. Here's the command on Linux ssh-keygen -t rsa -C "yourusername@youremailprovider.com" to create the keys.

Now you'll want to configure git with a few your user name and email. The commands for this are:

Configure git with user and email
git config --global user.name "yourusername"
git config --global user.email "yourusername@youremailprovider.com"


We're going to put our code up on GitHub first, so let's create an application first. Let's just use the default ramaze application and upload that (not exactly what I've done, but close enough). First go to your Dashboard on GitHub and create a new repository and call it "foo". This is where the application will live on GitHub. Now, run ramaze create foo to create an application called foo in the current directory. Then cd foo and we'll get the application ready to upload. We do need to add one file for Heroku and that's a .gems file. This file will contain a list of all the gems used by your application. In this case, the file should have the single line ramaze. If you're using Sequel say, the file would also contain a line sequel. In general it should have a line for each gem and the gem name should be what you would do by a sudo gem install xxx. Here we're going to run some git commands. I'm just learning git myself, but here's a book that should help you get started. The maintainer of this book, Scott Chacon, also has a dead tree book called "Pro Git" that is also quite good. So assuming we're in the foo directory already, type git init. This will get the application ready for git. Next we need to add the files with a git add . to add all the files in this directory and all of it's subdirectories into the repository. Now we need to do a "commit" of the files with a git commit -m 'first commit for foo'. Next, we'll tell git where we're going to save this with a git remote add origin git@github.com:slabounty/foo.git and finally, we'll push it to GitHub with git push origin master. You should now be able to go to your GitHub dashboard, see this repository and look at the files in there. Also, since this is a "public" repository, others will also be able to view and download these files, so don't use this for proprietary code unless you're using a non-free plan.

OK, let's move on to getting this up and running on Heroku. Start by creating an account on Heroku at http://heroku.com/. Once you have an account, you can sudo gem install heroku to get the Heroku gem. Next we'll do a heroku keys:add (this uses the same keys we created above to allow us to upload our files to Heroku. The one thing to make sure of is that you've created the .gems file as described above. Start with these two commands

git remote add origin git@github.com:slabounty/SimpleHeroku.git
git push origin master


Next we'll create an application on Heroku (we don't need to go to the website to do it, we'll just use the gem) with heroku create (creates an application on Heroku and let's you know where it's at. In my case it was http://smooth-stone-75.heroku.com) and finally we push it up to Heroku with a git push heroku master.

You can then point your browser where ever the application was created at, for example the web site above and you should see it running there. What is there is not the base Ramaze application that would be created but another simple one that I did. You should be able to see the code on GitHub.

There quite a bit of information here and if any of it is unclear, let me know.