Saturday, November 28, 2009

What If Hosting Was a Library?

# Was thinking, "if hosting was a library, what might it look like..."

require 'ProviderX'

# We'll pretend we already have an account with fictitious ProviderX

host = ProviderX.new(:user => 'foo', :password => 'secret')

# Let's see what ProviderX will allow us to deploy to

host.provides
> ['Amazon', 'Google']

# Let's create a new environment to deploy to

production = host.cloud.new(:vendor => 'Amazon', :name => 'production', :min_cpu => 2, :min_mem => 1024)

# We also would need to define the application that we wish to deploy

application = host.application.new(:repository => 'http://foo.com/foo.git', :type => 'Rails', :name => 'foo', :domain => 'foo.com', :ssl_enabled => true)

# All set! Let's deploy.

application.deploy_to production

application.deployed?
> true

application.deployed_to
> ['production']

production.applications
> ['foo']

# Maybe we forgot that we want to redirect www.foo.com to foo.com

application.redirects.add :from => 'www.foo.com', :to => 'foo.com'

# We don't want to deploy the code again, we just want to sync configuration changes (the redirect).

application.sync_configs production

# Perhaps we could control our resources from within our application

if production.swapping?
  production.ram.add 128
end

# That's it for my day-dreaming.

Saturday, September 27, 2008

Remove Gems By Prefix

If you are working with Merb or DM you know that approximately a gazillion gems are involved.  When, for whatever reason, I want to remove them it is a pain to do by hand.


Here is a simple script to help:

#!/bin/bash
prefix=$1
gem list --local | grep $prefix  | awk '{ print $1 }' | xargs sudo gem uninstall

I saved mine as remove_gem_by_prefix, gave it executable permissions and placed it in my path.

Now I can issue the commands:

$ remove_gem_by_prefix merb

or 

$ remove_gem_by_prefix dm

And they all get blasted.  You do need to be careful to make sure the prefix you provide is unique to the gems you wish to remove.

Saturday, September 13, 2008

Quick Remote Git Repository Creation Script

If you are using Git for your source code management, GitHub is an awesome tool. It especially shines for public projects where you freely allow others to fork your code and possibly pull patches back in.

Sometimes I'm just working on a project that I would prefer to keep in a private repository. GitHub provides paying accounts with such an option. However, I already have hosting accounts that are terribly underused. Here is a little script I use to create a remote git repository on one of my VPS accounts that I can then pull from and push to.

Prerequisites
A hosting account which you can ssh / scp into.

The Script

$ vim new_repo

#! /bin/sh
PWD=`pwd`

# You must adjust these variables for your specifc hosting account.
# Remote user you will connect as.
REMOTE_USER="admin"
# The IP address you will SSH / SCP to.
REMOTE_HOST="123.456.123.456"
# The remote path you wish to store your .git repositories in.
REMOTE_REPO_PATH="/home/admin/repos/"

if [ -d $1 ]; then
  echo "EXITING: Local directory '$1' already exists."
  exit 0
else
  mkdir $1
  cd $1
  git init-db
  touch README
  git add .
  git commit -m "Initial Repository Creation"
  cd ..
  git clone --bare $1/.git $1.git
  echo "** Copying new repository $1.git to $REMOTE_HOST:$REMOTE_REPO_PATH"
  scp -r $1.git $REMOTE_USER@$REMOTE_HOST:$REMOTE_REPO_PATH
  rm -rf $1.git
  rm -rf $1
  echo "** Cloning locally at $PWD/$1"
  git clone $REMOTE_USER@$REMOTE_HOST:$REMOTE_REPO_PATH$1.git
fi

exit 0

Or get it from GitHub

http://github.com/jpease/git-o-mator

Configuration

Of course, you will need to REMOTE_USER="admin" with an actual user on your hosting account, adjust REMOTE_HOST="123.456.123.456" to point to your accounts IP address, and edit REMOTE_REPO_PATH="/home/admin/repos/" with whatever path you wish to contain your Git repositories.

Once that is done, provide executable permissions.

$ chmod +x new_repo

That's it. Now if you execute:

$ ./new_repo testing

You will end up with /home/user/repos/testing.git on your remote host, and ./testing locally. From ./testing you can git push to send commits to the remote repository, and git pull to retrieve from the remote repository.

If you see room for improvement, I'm sure there is some, please leave a comment with your revision!

Monday, June 23, 2008

DataMapper: Many-to-many

You can define many-to-many associations using this syntax:

#item.rb
has n, :things, :through => Resource

#thing.rb
has n, :items, :through => Resource

In this case it will create a table items_things to manage the assignments. Easy enough. Depending on the relationship you are mapping out, it may make more sense to use the :through => :model syntax.

Now if you create an instance of an Item, you will get a method "things=". At first I thought this would be how you would assign a new Thing to your Item. Such as:

@item = Item.get(1)
@thing = Thing.get(1)
@item.things = @thing

FAIL! If you try adding a single Thing to your Item with this method you will receive a failure that the class you sent did not have a map method defined. Ah, ok. That makes sense, things= is obviously plural and will want an array of things. So how do you assign just one thing?

If you are unsure, a handy tool is to remember the "methods" method. So in this case you can try out:

@item.methods

You will see that you have not only a "things=" method, but also a plain old "things" method. If you try:

@item.things.methods

You will see that you have a << method, as should be expected. So to add our single Thing to our Item we do:

@item.things << @thing

That's it.

Friday, June 6, 2008

DataMapper: Parent / Child Relationship

I couldn't find an example at datamapper.org /docs for a parent child relationship.


After a little searching, I found the answer in the integration tests.  Here is the example:

class Node
include DataMapper::Resource

def self.default_repository_name
ADAPTER
end

property :id, Integer, :serial => true
property :name, String

has n, :children, :class_name => 'Node', :child_key => [ :parent_id ]
belongs_to :parent, :class_name => 'Node', :child_key => [ :parent_id ]

end

Hope that helps someone else.

Monday, March 3, 2008

Merb Monday: Vacation Edition

I'm on vacation visiting family (with limited Internet access). Back to semi-normal next week.

Monday, February 25, 2008

Merb Monday: The Leap Year Edition

News
Official documentation has been updated to include 0.9. Still a little light, but coming along. If you would like to help, create your own git branch and have at it!

Ivey had a baby. Congratulations!

Expect 0.9.1 (developer release) today (or soon).

You get an "extra" day this week. Use it wisely.

Teaser
Code name: Merblets.

Q&A

Q: What!? No RJS?

A: You can do anything rjs can do with *.js.erb templates (Answer by ezmobius)


Q: I read that Merb is template agnostic. What templates languages do I have available?

A: erb out of the box (erubis), haml (merb_haml as a dependency in init.rb), markaby (Answer by sqred)


Q: What does a named route in Merb look like?

A: r.match("/login").to(:controller => "Sessions", :action => "new").name(:login)
(Answer by jodo)


Q: Does Merb have a debugger tool?

A: You can use ruby-debug. Start Merb with the -D option to enable ruby-debug support.
Enter "debugger" somewhere in your code as a breakpoint. (Answer by jdempsey)


Q: How do I find out what version of Merb I'm using?

A: merb -v (Answer by ezmobius)


Q: How can I see the current routes?

A: merb -i
merb.show_routes
(Answer by ezmobius)


Q: Can the cookie session be used for large production apps?

A: As long as you don't store really sensitive info in the session then cookie sessions are fine (Answer by ezmobius)