Yukihiro Matsumoto - Ruby on Rails Podcast

Posted over 7 years back at Ruby on Rails Podcast

The creator of Ruby.
From RubyConf in Denver, Colorado.
Translation by Stephen Munday.

Ajax, Hobo Style

Posted over 7 years back at The Hobo Blog

OK, next up we’re going to see what Hobo brings to the Ajax table. In a nutshell – the ability to refresh fragments of a page without pushing them out into separate partial files. To see how that works, let’s knock up a quick demo application.

We’re going to build on the todo-list demo app from an earlier post, so if you want to follow along you should start with that post. Just to recap, the app is trivially simple, consisting of a TodoList model which has_many :tasks and a Task model which belongs_to :todo_list. We created a controller for to-do lists with just a show action, and we implemented a DRYML view for that action.

We’re going to add an ajaxified “New Task” form on that same page. Let’s do the back-end first, so that it’s possible to create tasks. We’ll start by being good modern Rails citizens, and switch to RESTful routing. Add this line to routes.rb:

map.resources :todo_lists, :tasks

Now create our controller

$ ./script/generate controller tasks

app/controllers/tasks_controller.rb

class TasksController < ApplicationController

  def create
    Task.create(params[:task])
  end

end

Now we’ll add a simple ajax form to todo_lists/show.dryml. We’ll use the familiar remote_form_tag helper. We’ll use raw HTML for the form controls, just to be clear about exactly what’s going on, What we won’t do, for now, is deal with refreshing the page.

app/views/todo_lists/show.dryml

<head>
  <%= javascript_include_tag :defaults %>
</head>
<body>
  <h1>Todo List: <name/></h1>

  <ul_for attr="tasks"><name_link/></ul_for>

  <% form_remote_tag :url => "/tasks", :method => :post do %>
    <input type="hidden" name="task[todo_list_id]"
                         value="<%= this.id %>"/>
    <input type="text" name="task[name]"/>
    <input type="submit" value="New Task"/>
  <% end %>
</body>

That should work as is, although you’ll have to manually reload the page to see any new tasks. Let’s fix that, Hobo style.

With DRYML, any fragment of the page can be marked as a part. A part can be rendered separately from the rest of the page, just like a partial. To create a part, just give any element a part_id. For this demo we’ll add it to the ul_for tag.

app/views/todo_lists/show.dryml

<head>
  <%= javascript_include_tag :defaults %>
</head>
<body>
  <h1>Todo List: <name/></h1>

  <ul_for attr="tasks" part_id="task_list"><name_link/></ul_for>

  <% form_remote_tag :url => "/tasks", :method => :post do %>
    <input type="hidden" name="task[todo_list_id]"
                         value="<%= this.id %>"/>
    <input type="text" name="task[name]"/>
    <input type="submit" value="New Task"/>
  <% end %>
</body>

Having done that, reload the page in the browser and have a look at the source. You should see something like (with bits cut out for the sake of clarity):

Generated HTML Source

<head>
  <!-- A BUNCH OF JAVASCRIPT INCLUDES -->
</head>
<body>
  <h1>Todo List: Launch Hobo!</h1>

  <span id='task_list'>
  <ul>
  <!-- A BUNCH OF LIST ITEMS -->
  </ul>
  </span>

<!-- THE FORM HERE -->
</body>

<script>
var hoboParts = {}
hoboParts.task_list = 'todo_list_1'
</script>

The important bits to note are the <span> with the same ID as our part, and the JavaScript snippet at the end. The JavaScript was generated by Hobo to keep track of which model objects are displayed in which parts.

We can ask for a part to be updated, simply by adding a few parameters to the request. Hobo provides tags to make this blissfully easy, and we’ll have a look at those shortly. For now though, just to show there’s no magic going on, we’ll add them by hand using hidden fields.

The parameters we need are:

* part_page: The path of the current page template, e.g. “todo_lists/show”. (Future development: maybe we can do away with this and use the HTTP referrer instead)

* render[][part]: The name of the part we’d like to refresh. e.g. task_list

* render[][object]: The “DOM ID” of the “context object” for that part. e.g. todo_list_1

Update the form as follows:

app/views/todo_lists/show.dryml (fragment)

<% form_remote_tag :url => "/tasks", :method => :post do %>
  <input type="hidden" name="task[todo_list_id]"
                       value="<%= this.id %>"/>
  <input type="text" name="task[name]"/>
  <input type="submit" value="New Task"/>

  <input type="hidden" name="part_page" value="todo_lists/show"/>
  <input type="hidden" name="render[][part]" value="task_list"/>
  <input type="hidden" name="render[][object]"
                       value="todo_list_<% this.id %>"/>
<% end %>

We now need to upgrade our controller to recognize this “render request”. That just requires including a module, and calling one method:

app/controllers/tasks_controller.rb

class TasksController < ApplicationController

  include Hobo::AjaxController

  def create
    this = Task.create(params[:task])
    hobo_ajax_response(this)
  end

end

The hobo_ajax_response method needs a page context. As you can see we’re passing in the object just created.

You should now have a working ajax “New Task” feature.

The code might work but it’s pretty ugly (heh). Let’s clean it up using the appropriate Hobo tags. The tags we need come from a tag library that’s provided with Hobo – Hobo Rapid. Hobo Rapid is a very general purpose tag library that makes it extremely quick and easy to do the bread-and-butter stuff: links, forms, ajax…

We’ll look at Hobo Rapid in more detail in another post. For now we’ll see how to pretty-up our ajax demo.

To include Hobo Rapid in your application:

$ ./script/generate hobo_rapid

Then edit your view to look as follows:

app/views/todo_lists/show.dryml

<head>
  <%= javascript_include_tag :defaults %>
  <hobo_rapid_javascripts/>
</head>
<body>
  <h1>Todo List: <name/></h1>

  <ul_for attr="tasks" part_id="task_list"><name_link/></ul_for>

  <create_form attr="tasks" update="task_list">
    <edit attr="name"/>
    <submit label="New Task"/>
  </create_form>
</body>

Yep - that’s it :-) Try it – it should be working.

The <create_form> tag can be read as: Include a form which will first create an object in the collection “tasks” of the current context (the TodoList), and then update the ”task_list” part. Note that you don’t need to say anything about how to update that part. Hobo knows.

<booming-voice>AND NOW drum-roll THE GRAND FINALE…</booming-voice>

How easy is it to update multiple parts in one go? For example, suppose the page had a count of the number of tasks – that would need updating too. We’ll use another handy little tag from Hobo Rapid: <count> (Note this tag doesn’t have any special ajax support. We could have used a regular ERB scriptlet and the ajax would still work). And for bonus marks, we’ll DRY up all those attr='tasks' using a <with> tag, which just changes the context.

app/views/todo_lists/show.dryml

<head>
  <%= javascript_include_tag :defaults %>
  <hobo_rapid_javascripts/>
</head>
<body>
  <h1>Todo List: <name/></h1>

  <with attr="tasks">
    <ul_for part_id="task_list"><name_link/></ul_for>
    <p><count part_id="task_count"/></p>

    <create_form update="task_list, task_count">
      <edit attr="name"/>
      <submit label="New Task"/>
    </create_form>
  </with>
</body>

To update multiple parts, just list the part names in the update attribute.

What more could you ask for? :-)

Ajax, Hobo Style

Posted over 7 years back at The Hobo Blog

OK, next up we’re going to see what Hobo brings to the Ajax table. In a nutshell – the ability to refresh fragments of a page without pushing them out into separate partial files. To see how that works, let’s knock up a quick demo application.

We’re going to build on the todo-list demo app from an earlier post, so if you want to follow along you should start with that post. Just to recap, the app is trivially simple, consisting of a TodoList model which has_many :tasks and a Task model which belongs_to :todo_list. We created a controller for to-do lists with just a show action, and we implemented a DRYML view for that action.

We’re going to add an ajaxified “New Task” form on that same page. Let’s do the back-end first, so that it’s possible to create tasks. We’ll start by being good modern Rails citizens, and switch to RESTful routing. Add this line to routes.rb:

map.resources :todo_lists, :tasks

Now create our controller

$ ./script/generate controller tasks

app/controllers/tasks_controller.rb

class TasksController < ApplicationController

  def create
    Task.create(params[:task])
  end

end

Now we’ll add a simple ajax form to todo_lists/show.dryml. We’ll use the familiar remote_form_tag helper. We’ll use raw HTML for the form controls, just to be clear about exactly what’s going on, What we won’t do, for now, is deal with refreshing the page.

app/views/todo_lists/show.dryml

<head>
  <%= javascript_include_tag :defaults %>
</head>
<body>
  <h1>Todo List: <name/></h1>

  <ul_for attr="tasks"><name_link/></ul_for>

  <% form_remote_tag :url => "/tasks", :method => :post do %>
    <input type="hidden" name="task[todo_list_id]"
                         value="<%= this.id %>"/>
    <input type="text" name="task[name]"/>
    <input type="submit" value="New Task"/>
  <% end %>
</body>

That should work as is, although you’ll have to manually reload the page to see any new tasks. Let’s fix that, Hobo style.

With DRYML, any fragment of the page can be marked as a part. A part can be rendered separately from the rest of the page, just like a partial. To create a part, just give any element a part_id. For this demo we’ll add it to the ul_for tag.

app/views/todo_lists/show.dryml

<head>
  <%= javascript_include_tag :defaults %>
</head>
<body>
  <h1>Todo List: <name/></h1>

  <ul_for attr="tasks" part_id="task_list"><name_link/></ul_for>

  <% form_remote_tag :url => "/tasks", :method => :post do %>
    <input type="hidden" name="task[todo_list_id]"
                         value="<%= this.id %>"/>
    <input type="text" name="task[name]"/>
    <input type="submit" value="New Task"/>
  <% end %>
</body>

Having done that, reload the page in the browser and have a look at the source. You should see something like (with bits cut out for the sake of clarity):

Generated HTML Source

<head>
  <!-- A BUNCH OF JAVASCRIPT INCLUDES -->
</head>
<body>
  <h1>Todo List: Launch Hobo!</h1>

  <span id='task_list'>
  <ul>
  <!-- A BUNCH OF LIST ITEMS -->
  </ul>
  </span>

<!-- THE FORM HERE -->
</body>

<script>
var hoboParts = {}
hoboParts.task_list = 'todo_list_1'
</script>

The important bits to note are the <span> with the same ID as our part, and the JavaScript snippet at the end. The JavaScript was generated by Hobo to keep track of which model objects are displayed in which parts.

We can ask for a part to be updated, simply by adding a few parameters to the request. Hobo provides tags to make this blissfully easy, and we’ll have a look at those shortly. For now though, just to show there’s no magic going on, we’ll add them by hand using hidden fields.

The parameters we need are:

* part_page: The path of the current page template, e.g. “todo_lists/show”. (Future development: maybe we can do away with this and use the HTTP referrer instead)

* render[][part]: The name of the part we’d like to refresh. e.g. task_list

* render[][object]: The “DOM ID” of the “context object” for that part. e.g. todo_list_1

Update the form as follows:

app/views/todo_lists/show.dryml (fragment)

<% form_remote_tag :url => "/tasks", :method => :post do %>
  <input type="hidden" name="task[todo_list_id]"
                       value="<%= this.id %>"/>
  <input type="text" name="task[name]"/>
  <input type="submit" value="New Task"/>

  <input type="hidden" name="part_page" value="todo_lists/show"/>
  <input type="hidden" name="render[][part]" value="task_list"/>
  <input type="hidden" name="render[][object]"
                       value="todo_list_<% this.id %>"/>
<% end %>

We now need to upgrade our controller to recognize this “render request”. That just requires including a module, and calling one method:

app/controllers/tasks_controller.rb

class TasksController < ApplicationController

  include Hobo::AjaxController

  def create
    this = Task.create(params[:task])
    hobo_ajax_response(this)
  end

end

The hobo_ajax_response method needs a page context. As you can see we’re passing in the object just created.

You should now have a working ajax “New Task” feature.

The code might work but it’s pretty ugly (heh). Let’s clean it up using the appropriate Hobo tags. The tags we need come from a tag library that’s provided with Hobo – Hobo Rapid. Hobo Rapid is a very general purpose tag library that makes it extremely quick and easy to do the bread-and-butter stuff: links, forms, ajax…

We’ll look at Hobo Rapid in more detail in another post. For now we’ll see how to pretty-up our ajax demo.

To include Hobo Rapid in your application:

$ ./script/generate hobo_rapid

Then edit your view to look as follows:

app/views/todo_lists/show.dryml

<head>
  <%= javascript_include_tag :defaults %>
  <hobo_rapid_javascripts/>
</head>
<body>
  <h1>Todo List: <name/></h1>

  <ul_for attr="tasks" part_id="task_list"><name_link/></ul_for>

  <create_form attr="tasks" update="task_list">
    <edit attr="name"/>
    <submit label="New Task"/>
  </create_form>
</body>

Yep - that’s it :-) Try it – it should be working.

The <create_form> tag can be read as: Include a form which will first create an object in the collection “tasks” of the current context (the TodoList), and then update the ”task_list” part. Note that you don’t need to say anything about how to update that part. Hobo knows.

<booming-voice>AND NOW drum-roll THE GRAND FINALE…</booming-voice>

How easy is it to update multiple parts in one go? For example, suppose the page had a count of the number of tasks – that would need updating too. We’ll use another handy little tag from Hobo Rapid: <count> (Note this tag doesn’t have any special ajax support. We could have used a regular ERB scriptlet and the ajax would still work). And for bonus marks, we’ll DRY up all those attr='tasks' using a <with> tag, which just changes the context.

app/views/todo_lists/show.dryml

<head>
  <%= javascript_include_tag :defaults %>
  <hobo_rapid_javascripts/>
</head>
<body>
  <h1>Todo List: <name/></h1>

  <with attr="tasks">
    <ul_for part_id="task_list"><name_link/></ul_for>
    <p><count part_id="task_count"/></p>

    <create_form update="task_list, task_count">
      <edit attr="name"/>
      <submit label="New Task"/>
    </create_form>
  </with>
</body>

To update multiple parts, just list the part names in the update attribute.

What more could you ask for? :-)

The Liquid Chronicles - The Setup

Posted over 7 years back at Eric Goodwin

I've been playing with liquid templates in rails now for about a month. When I first started there wasn't a great deal of nice, easy to follow, step by step tutorials. There are a few good wiki's but putting all the information together can be a bit quite a bit of work.This guide is meant to be super simple and easy to follow. It will be a start to finish guide on how to install and use liquid in you ruby on rails application. This is part one. Enjoy!
First let's create our project and add the liquid rails plugin.

server:/# cd /rails
server:/# rails liquid
server:/# cd liquid/vendor/plugins
server:/# svn export svn://home.leetsoft.com/liquid/trunk/liquid/
server:/# cd ../../
server:/# rake rails:freeze:edge
server:/# ruby script/server

After starting the server you should be able to see the default rails page.
Now that you have your server up and running create your database and add the right settings to your database.yml.
Now let's get rid of the default rails page and add a couple routes so we'll be able to see our new page that we are going to create a bit later.
server:/# rm public/index.html
server:/# pico config/routes.rb

Add the following lines to the routes.rb file.
1
2
map.resources :posts
map.connect '', :controller => "posts"

Now we need to create our database table. We are going to create a super simple blog, so let's add a posts table.
server:/# cd db
server:/# mkdir migrate
server:/# cd migrate
server:/# pico 001_create_posts.rb

Here is our code for the migration
1
2
3
4
5
6
7
8
9
10
11
12
13
class CreatePosts < ActiveRecord::Migration
  def self.up
    create_table :posts do |t|
      t.column :title, :string
      t.column :body, :text
      t.column :created_at, :datetime
    end
  end

  def self.down
    drop_table :posts
  end
end

Now lets run a migration to generate the table in our database. After that we'll create our post resource and then restart the server to make sure that everything is still working properly.
server:/# rake db:migrate
server:/# ruby script/generate scaffold_resource post
server:/# ruby script/server

You should now be able to go to http://localhost:3000 and see the scaffolding for your new site. Now all we have to do is add some liquid.
Let's edit our posts controller first.
server:/# pico app/controllers/posts_controller.rb

In the index method let's change the default find statement.
1
2
#@posts = Post.find(:all)
@posts = Post.find(:all).collect(&:attributes)

This last line might be a bit confusing. Basically all that it is doing is grabbing all of our posts and then creating hashes for each one with all of its attributes. Since liquid likes to use hashes we need to do this conversion.
Now that we have some hashes to work with we need to create our liquid view.
server:/# cd app/views/post
server:/# mv index.rhtml index.liquid
server:/# pico index.liquid

We're going to simplify our index view a little and take out all the editing capabilities and add some liquid methods. For liquid syntax, check out this site.
1
2
3
4
5
6
7
8
9
10
<h1>Our Posts</h1>
<div id="posts">
{% for post in posts %}
        <div class="post">
                <h2>{{ post.title }}</h2>
                <p class="date">{{ post.created_at | date:"%b %d, %Y" }}</p>
                <p>{{ post.body }}</p>
        </div>
{% endfor %}
</div>

Ok .. now that that's all done we can add a couple records to the database. When we restart the server we should be able to see the records. We should probably add our main layout as a liquid template as well.
server:/# pico app/controllers/posts_controller.rb

Add this line just after the class definition

layout 'default'

Now we just have to make the default liquid template in our views/layout directory.
server:/# pico app/views/layouts/default.liquid

Here is what we're going to start with.
1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>My Liquid Enabled Site</title>
  <link rel="Stylesheet" href="/stylesheets/scaffold.css" type="text/css" media="screen" />
</head>
<body>
{{ content_for_layout }}
</body>
</html>

Now your on your way to becoming a pro liquid user. Stay tuned for our next installment, Liquid Drops.
For more information on liquid check out these resources

The Liquid Chronicles - The Setup

Posted over 7 years back at Eric Goodwin

I've been playing with liquid templates in rails now for about a month. When I first started there wasn't a great deal of nice, easy to follow, step by step tutorials. There are a few good wiki's but putting all the information together can be a bit quite a bit of work.This guide is meant to be super simple and easy to follow. It will be a start to finish guide on how to install and use liquid in you ruby on rails application. This is part one. Enjoy!
First let's create our project and add the liquid rails plugin.

server:/# cd /rails
server:/# rails liquid
server:/# cd liquid/vendor/plugins
server:/# svn export svn://home.leetsoft.com/liquid/trunk/liquid/
server:/# cd ../../
server:/# rake rails:freeze:edge
server:/# ruby script/server

After starting the server you should be able to see the default rails page.
Now that you have your server up and running create your database and add the right settings to your database.yml.
Now let's get rid of the default rails page and add a couple routes so we'll be able to see our new page that we are going to create a bit later.
server:/# rm public/index.html
server:/# pico config/routes.rb

Add the following lines to the routes.rb file.
1
2
map.resources :posts
map.connect '', :controller => "posts"

Now we need to create our database table. We are going to create a super simple blog, so let's add a posts table.
server:/# cd db
server:/# mkdir migrate
server:/# cd migrate
server:/# pico 001_create_posts.rb

Here is our code for the migration
1
2
3
4
5
6
7
8
9
10
11
12
13
class CreatePosts < ActiveRecord::Migration
  def self.up
    create_table :posts do |t|
      t.column :title, :string
      t.column :body, :text
      t.column :created_at, :datetime
    end
  end

  def self.down
    drop_table :posts
  end
end

Now lets run a migration to generate the table in our database. After that we'll create our post resource and then restart the server to make sure that everything is still working properly.
server:/# rake db:migrate
server:/# ruby script/generate scaffold_resource post
server:/# ruby script/server

You should now be able to go to http://localhost:3000 and see the scaffolding for your new site. Now all we have to do is add some liquid.
Let's edit our posts controller first.
server:/# pico app/controllers/posts_controller.rb

In the index method let's change the default find statement.
1
2
#@posts = Post.find(:all)
@posts = Post.find(:all).collect(&:attributes)

This last line might be a bit confusing. Basically all that it is doing is grabbing all of our posts and then creating hashes for each one with all of its attributes. Since liquid likes to use hashes we need to do this conversion.
Now that we have some hashes to work with we need to create our liquid view.
server:/# cd app/views/post
server:/# mv index.rhtml index.liquid
server:/# pico index.liquid

We're going to simplify our index view a little and take out all the editing capabilities and add some liquid methods. For liquid syntax, check out this site.
1
2
3
4
5
6
7
8
9
10
<h1>Our Posts</h1>
<div id="posts">
{% for post in posts %}
        <div class="post">
                <h2>{{ post.title }}</h2>
                <p class="date">{{ post.created_at | date:"%b %d, %Y" }}</p>
                <p>{{ post.body }}</p>
        </div>
{% endfor %}
</div>

Ok .. now that that's all done we can add a couple records to the database. When we restart the server we should be able to see the records. We should probably add our main layout as a liquid template as well.
server:/# pico app/controllers/posts_controller.rb

Add this line just after the class definition

layout 'default'

Now we just have to make the default liquid template in our views/layout directory.
server:/# pico app/views/layouts/default.liquid

Here is what we're going to start with.
1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
  <title>My Liquid Enabled Site</title>
  <link rel="Stylesheet" href="/stylesheets/scaffold.css" type="text/css" media="screen" />
</head>
<body>
{{ content_for_layout }}
</body>
</html>

Now your on your way to becoming a pro liquid user. Stay tuned for our next installment, Liquid Drops.
For more information on liquid check out these resources

RJS & MinusMOR

Posted almost 8 years back at zerosum dirt(nap) - Home

RJS rocks. It lets me write JavaScript without writing any JavaScript. That’s very Zen, and I like it. But sometimes I find myself writing really ugly, narsty things in my RJS templates. Instead of using Ruby to write JavaScript I end up writing JavaScript and appending it to the page with Ruby, especially when client side conditionals are involved. Needless to say, the template code quickly devolves into what can only be described as frankenrubyscript.

To rid ourselves of the monster, take a look at Dan Webb’s MinusMOR plugin, which lets you return plain ol JavaScript to the browser using templates with an .ejs file extension. This may not seem like a big deal but it’s pretty damn helpful if you return any significant amount of client-side logic within RJS.

[Note that you’ll need to be on the Rails 1.2 codebase to use the plugin]

As a simple example, let’s overhaul our sample YUI test app to use MinusMOR. Now this really isn’t a great example, as the JavaScript code is super simple and therefore lends itself well to being written in Ruby. But oh well. At least it gives you an idea of how it works.

Our add.rjs file used to contain the following one-liner:

page.replace_html 'hello_msg', @thing[:name]

Now, our add.ejs file will contain the following code instead. Note the use of ERb in the template:

document.getElementById('hello_msg').innerHTML = '<%=@thing[:name]%>';

In this case the normal RJS approach is quicker, sexier, and, above all else, easier to read. And, admittedly, 90% of your client-side code will more than likely be the simple kind of stuff that RJS rocks at (update this text within that DIV, switch the visible state of that DOM element to hidden, etc). But you can certainly imagine scenarios where it’d make sense to write pure JavaScript in the template instead.

Use RJS wherever you can, but once bits and pieces of frankenrubyscript start sneaking into your code, be sure to check out Dan’s plugin. Cuz there’s no denying that there are cases where using plain ol JavaScript is cleaner, as un-Zen-like as that may seem….!

Pastures New

Posted almost 8 years back at Luke Redpath - Home

Last Thursday was my last day working for Agile Evolved. I enjoyed my time at AE and want to say thanks to Jonathan for employing me in the first place and giving me the opportunity to grow as a programmer, work full-time with Ruby and Rails, contribute to the open-source community and to become an active part of the London Ruby community. Good luck to everybody at Agile Evolved!

The new job

This Monday I started my new job as Head of Software Development for a London-based media company. Unfortunately, at the request of my employers I’m unable to say who I am working for — don’t get excited, it isn’t anybody you would have heard of anyway (probably) but I am really excited about the challenges I will be facing over the coming months.

Obviously there is little I can say about what I will be working on at this moment in time but needless to say we will be fully utilizing the power of Ruby and RubyOnRails and other open source software on several large-scale projects in what could be one of the largest-scale deployments of a Ruby/Rails application. Exciting stuff! I’ll try and post information on how we are using Ruby whenever I possibly can, confidentiality and approval from our PR department pending of course.

Project updates

Some of you may be wondering where this leaves the numerous open-source projects that I am working on. Naturally, I will be very busy over the coming months but I was keen to stress that how important contributing to open-source software was to my new employers and I have their full support so my involvement will continue pretty much as it is, as will my participation in the Ruby community…I’ll have to drag our CTO (aka my boss) down to the next LRUG meeting.

Dan and I will do our best to get a new release of UJS out of the door before the end of the year. It is most likely that we will put back any new features to a 0.5 release and concentrate on bugs and Rails 1.2 compatibility for 0.4. My work on ActiveSpec will most likely be put off until the new year now. Meanwhile, James and I are almost ready with the official Rails plugin repository — it should hopefully be ready in time for the Rails 1.2 final release.

I’m also happy to announce that I have officially joined the RSpec development team. My initial contributions will likely be towards the RSpec TextMate bundle but I hope to get even more involved in the new year.

And finally…

On the subject of moving on, I recently moved my blog from Site5 to a Rimuhosting VPS. Site5 weren’t bad for a shared host but they had no Mongrel support and frankly FastCGI and Rails is just painful.

For those interested in my setup, I have two allocated IP addresses – I’m running Nginx on one IP as a proxy to Mongrel for any Rails apps (currently just this blog) and lighttpd on the second IP address for serving up any static content or PHP apps that I might need (such as Mint Stats and Roundcube Webmail). The setup works well and was easy to get up and running — not having to use Apache 2.2 also saves me plenty of resources which is great because I only have 160MB of RAM to play with on my current plan.

I really recommend a VPS if you are running Rails apps and Rimuhosting are very good value for money. The only pain for me was setting up my mail server with Postfix, Dovecot and SpamAssassin which was a new and painful experience for me. I got there in the end though and I can now have my own Subversion repositories and I will eventually have an instance of Trac up and running for my various open-source projects. Stay tuned!

Hello Mephisto

Posted almost 8 years back at Eric Goodwin

After putting it off for sometime now, I just switched over from Typo to Mephisto. There are going to be a couple of glitches in the changeover but hopefully everything should be up and running smoothly in the next week or so.

Hello Mephisto

Posted almost 8 years back at Eric Goodwin

After putting it off for sometime now, I just switched over from Typo to Mephisto. There are going to be a couple of glitches in the changeover but hopefully everything should be up and running smoothly in the next week or so.

Moving To The Edge, Or Thereabouts

Posted almost 8 years back at zerosum dirt(nap) - Home

So I tried to update my OS X dev box to GemRails 1.2 RC 1 and ran into some issues the other day. For some reason, I just couldn’t seem to get system Rails pointing to the new (.5618) copy. I’m usually a pretty stubborn bastard, but one of the plugins I wanted to use requires exempt_from_layout to be available on ActionController::Base, so I figured I’d use EdgeRails and freeze a copy of 1.2 RC 1 in the project’s vendors directory.

One of the nice things about the way this is all wired together is that you don’t have to be on the very edge of EdgeRails to take advantage of it. In this case, I just need some functionality in 1.2 RC 1 so I can update our existing project and check out using the tag:

rake rails:freeze:edge TAG=rel_1-2-0_RC1

To verify that we’re on EdgeRails now using the 1.2 codebase (so we can hang out with the cool kids), we can run script/about:

Edge Rails revision rel_1-2-0_RC1

Keep in mind that this is different than just doing a regular edge freeze since we know we’re getting exactly what we’re asking for. If we just issued an edge freeze without the TAG parameter we’re going to get the latest and greatest development version which of course means two things: 1) we get the bestest newest coolest stuff, and 2) there’s a good chance that some of that stuff is a bit buggy.

For the moment, we don’t have an immediate need to be running the very latest and will therefore generally tend toward valuing stability over freshness. But as our projects grow and we shed more and more of our noobskin, I’m sure we’ll begin making even more exceptions to that rule, forcing us ever closer to the bleeding edge.

Pun intended, of course.

Superfast Testing How To: In-Memory SQLite3

Posted almost 8 years back at Wood for the Trees

Audience: This is for both application and plugin developers. Especially plugin developers. Always use SQLite3 in-memory databases as your default for plugin tests which require a database.

Some of you may have heard of SQLite3, played with it and decided it is too limited or don’t like the files which it creates in your project tree. There is a less-sung alternative which is much, much faster (actual benchmarks vary because of memory speeds, but for me PostgreSQL is about 33% slower and MySQL about 10% slower). Over a large testing library with thousands of assertions, you will feel that meagre 10% by a comfortable minute. Slight disadvantage: you can’t get that coffee during testing anymore!

There are a handful of sites which have spoken of SQLite3 in-memory databases this year, but to get it working you’ll find the information is a little scattered. The following is a step-by-step ‘how to’ on making your application and plugin tests superfast and lightweight, but please read over these pages first:

Set Up

A lot of this doesn’t need much explanation, so I’m just going to dump out the procedure to get you from MySQL/PostgreSQL/whatever testing to SQLite3 in-memory database testing, making you wait less and code more.

Step 1: Install SQLite3 and friends

If you do not have SQLite3 already, you need to go to the SQLite website and download the appropriate package. If you use Mac OS X, you need to install the SWIG library too.

Once you have the latest SQLite3 distribution, you need to install the sqlite3-ruby gem:

  user@host railsproj$ sudo gem install sqlite3-ruby --source code.whytheluckystiff.net

Select the highest ‘(ruby)’ version (1.1.0.1 at the time of this article). You should see it compile a native extension and install without a hitch.

Note: If you already have sqlite3-ruby installed but do not remember seeing a native extension being compiled, you should uninstall (`gem uninstall sqlite3-ruby`) and install it again with the SWIG library.

Step 2: Install the Memory Test Fix plugin

  user@host railsproj$ ./script/plugin install http://topfunky.net/svn/plugins/memory_test_fix

Step 3: Change RAILS_ROOT/config/database.yml

test:
  adapter: sqlite3
  database: ":memory:"
  verbosity: quiet

Note: remove `verbosity: quiet` at the beginning to make sure SQLite3 is loading your db/schema.rb file. If you are not using Migrations or db/schema.rb, you will also need to set `config.active_record.schema_format = :sql` in your environment files and point Rails to the correct schema file.

Step 4: Test it

  user@host railsproj$ rake test

Notes

As TopFunky says: if you use database specific SQL, using SQLite3 will only get in the way.

Superfast Testing How To: In-Memory SQLite3

Posted almost 8 years back at Wood for the Trees

Audience: This is for both application and plugin developers. Especially plugin developers. Always use SQLite3 in-memory databases as your default for plugin tests which require a database.

Some of you may have heard of SQLite3, played with it and decided it is too limited or don’t like the files which it creates in your project tree. There is a less-sung alternative which is much, much faster (actual benchmarks vary because of memory speeds, but for me PostgreSQL is about 33% slower and MySQL about 10% slower). Over a large testing library with thousands of assertions, you will feel that meagre 10% by a comfortable minute. Slight disadvantage: you can’t get that coffee during testing anymore!

There are a handful of sites which have spoken of SQLite3 in-memory databases this year, but to get it working you’ll find the information is a little scattered. The following is a step-by-step ‘how to’ on making your application and plugin tests superfast and lightweight, but please read over these pages first:

Set Up

A lot of this doesn’t need much explanation, so I’m just going to dump out the procedure to get you from MySQL/PostgreSQL/whatever testing to SQLite3 in-memory database testing, making you wait less and code more.

Step 1: Install SQLite3 and friends

If you do not have SQLite3 already, you need to go to the SQLite website and download the appropriate package. If you use Mac OS X, you need to install the SWIG library too.

Once you have the latest SQLite3 distribution, you need to install the sqlite3-ruby gem:

  user@host railsproj$ sudo gem install sqlite3-ruby --source code.whytheluckystiff.net

Select the highest ‘(ruby)’ version (1.1.0.1 at the time of this article). You should see it compile a native extension and install without a hitch.

Note: If you already have sqlite3-ruby installed but do not remember seeing a native extension being compiled, you should uninstall (`gem uninstall sqlite3-ruby`) and install it again with the SWIG library.

Step 2: Install the Memory Test Fix plugin

  user@host railsproj$ ./script/plugin install http://topfunky.net/svn/plugins/memory_test_fix

Step 3: Change RAILS_ROOT/config/database.yml

test:
  adapter: sqlite3
  database: ":memory:"
  verbosity: quiet

Note: remove `verbosity: quiet` at the beginning to make sure SQLite3 is loading your db/schema.rb file. If you are not using Migrations or db/schema.rb, you will also need to set `config.active_record.schema_format = :sql` in your environment files and point Rails to the correct schema file.

Step 4: Test it

  user@host railsproj$ rake test

Notes

As TopFunky says: if you use database specific SQL, using SQLite3 will only get in the way.

ActiveTest: TestHelper Bug Fix

Posted almost 8 years back at Wood for the Trees

There was an issue with test_helper variables set on Test::Unit::TestCase not being set properly. Values would always be the default because of the way class inherited attributes are passed down the hierarchy. You now need to require the active_test framework and any other plugins you have installed at the end of RAILS_ROOT/test/test_helper.rb.

Also, plugin developers should never require their libraries through init. Instead, there should be a file with the name of their plugin in PLUGIN_ROOT/lib. For example, active_test_authentication has a file at PLUGIN_ROOT/lib/active_test_authentication.rb. This is the file which is loaded when `require ‘active_test_authentication’` is called at the end of test_helper.

This fix actually alleviates more than google issue 2. When loaded plugins with a name lexicographically earlier than active_test, active_test would automatically be loaded. This is trivial, but not intended. In any case, you must now require both the active_test framework and any plugins you use at the end of test_helper.

ActiveTest: TestHelper Bug Fix

Posted almost 8 years back at Wood for the Trees

There was an issue with test_helper variables set on Test::Unit::TestCase not being set properly. Values would always be the default because of the way class inherited attributes are passed down the hierarchy. You now need to require the active_test framework and any other plugins you have installed at the end of RAILS_ROOT/test/test_helper.rb.

Also, plugin developers should never require their libraries through init. Instead, there should be a file with the name of their plugin in PLUGIN_ROOT/lib. For example, active_test_authentication has a file at PLUGIN_ROOT/lib/active_test_authentication.rb. This is the file which is loaded when `require ‘active_test_authentication’` is called at the end of test_helper.

This fix actually alleviates more than google issue 2. When loaded plugins with a name lexicographically earlier than active_test, active_test would automatically be loaded. This is trivial, but not intended. In any case, you must now require both the active_test framework and any plugins you use at the end of test_helper.

Sample Rails Application – A demo for the ajax based drag drop tree in rubyonrails

Posted almost 8 years back at Ajax on Rails


I have provided the source code of the ajax based drag drop tree in rubyonrails in one of my previous posts.
I found some of the people are getting problems to incorporate the code into their running applications so i am providing a sample rails application in which all the code for tree is already been placed well.
However the code written seems to be lagged behind the current trends followed in rails development coz of the fire growth of rails itself, but its simply that when i wrote this tree i was very new to rails so you may find the code looks like an old wine but still tastes good to go with.

CHECK THIS OUT…

Four simple steps to make the tree working…

  1. DOWNLOAD the sample application. (let me know if you are getting any error in downloading the application.)
  2. Create a test database in mysql or modify the file /config/database.yml according to the database and user u need.
  3. Run the command
    ajaxtree> rake db:migrate

    from the application root.

  4. Run the application server by running
    ajaxtree> ruby script/server

    and watch the working tree at http://localhost:3000