IntelliJ On Rails

Posted over 7 years back at zerosum dirt(nap) - Home

If you’re an IntelliJ user like me, and have recently been bitten by the RoR bug, you’ll be glad to know that there’s a plugin on the way. It’s still in it’s infancy, lacking a lot of features, and is therefore not in the repository, but that doesn’t mean we can’t play around with it. What follows is a brief tutorial on how to locate, install, and use the ruby plugin…

First you need to check out the sources from the Subversion repo:

svn co http://svn.jetbrains.org/idea/Trunk/ruby

Use Ant to build it (run ant from the directory you co’d to, where the build.xml file lives). The build process should generate a jar file in dist/ called ruby-SNAPSHOT.jar.

Next, make a new directory in your IDJ plugins directory called ‘ruby’ and make a lib directory in there. Copy the jar to $IDJ_ROOT/plugins/ruby/lib. On OS X, this path is something like /Applications/IntelliJ IDEA 6.0.2.app/plugins/ruby/lib/.

Start IntelliJ. Go to Settings → Project Settiings → Project Structure. In Global Resources, under JDKs, right click and add a Ruby SDK. On OS X, you’ll want to point it at /usr/local, or whereever your copy of Ruby has been installed.

Now you should be able to create a new project and select Ruby SDK from the JDK list (heh). Create a single module project, select Rails as your module type, and set the Ruby SDK for the module. Finally, you’ll be given the chance to generate a new Rails application skeleton, generate missing files, or use an existing Rails app. Go ahead and create a test project and generate a new Rails framework. I’ll do all the work for you and populate the project explorer with that oh-so-familiar directory structure. Check out that ugly Ruby icon they’re using. Jeeze, what is that?

Right click in the project explorer and select New → Controller. Name your controller test and add an action name hello. Click OK. IDJ will run the Rails generator and update the project explorer. You now have a TestController with a hello action, the corresponding view template, and the expected test stubs.

You can select Run → Run… to start a WEBrick server and test your app. There are some bugs here. First of all, there is no run output in the console view where you’d expect it to be. No web browser is launched, no indication is given of what port number the server gets bound to. Worse, you can’t seem to kill a running WEBrick server without killing the process from a terminal. So yeah, there’s obviously still some work to do here. For now, I’d suggest running WEBrick from the command line (RadRails still wins here, at least). No command completion or real debugging support is available yet either, but hey.. it’s a start. It’s functional, you can run tests from within the IDE, you get basic code formatting, syntax highlighting, etc.

For more information, check out the JetBrains Project Homepage for the ruby plugin, where you’ll find a link to the roadmap and discussion groups. You’ll note that there are plans for autocompletion, ability to browse to symbol, proper YAML, RXML support, etc. I really hope that development continues on this. IDJ is much-loved amongst the Java community, and could be a huge hit in the Rails community if they get a slick, fully functional plugin out there.

Develop with pleasure ;-).

Relief

Posted over 7 years back at zerosum dirt(nap) - Home

So we just finished wrapping up work on the app we’ve been building for the past 8 months. Yay! It’s part of a suite of web-powered tools for a certain niche video editing system. Implemented in Java, leveraging Swing, Axis, WebObjects… Great project and totally learned a lot, but sure am relieved to have delivered it. I’m sure there’ll be a tweak to make here or there, but you know… It’s delivered (rc).

What’s next? Well, I’m not entirely sure to be honest. For the first time in my life I’m thinking about abandoning paid work in order to invest a couple solid months of full-time effort working on the Ruby/Rails app that’s in my head. Perhaps it’s finally time to put my neck out there a little and make it happen. After all, I isn’t getting any younger, now is I?

Fun with IIS : Unexpected Error 0x8ffe2740 Occurred

Posted over 7 years back at Eric Goodwin

I installed IIS on my computer the other day because I'm doing some work for a client who is using ASP. When I tried to start up the server, I got this error message 'Unexpected Error 0x8ffe2740 Occurred'. Having no idea what error 0x8ffe2740 was I hit up google for some answers. Turns out Error 0x8ffe2740 means Port already in use. It would have been nice if they had just supplied a simple explanation in there error message. Is that too much to ask for?

Fun with IIS : Unexpected Error 0x8ffe2740 Occurred

Posted over 7 years back at Eric Goodwin

I installed IIS on my computer the other day because I'm doing some work for a client who is using ASP. When I tried to start up the server, I got this error message 'Unexpected Error 0x8ffe2740 Occurred'. Having no idea what error 0x8ffe2740 was I hit up google for some answers. Turns out Error 0x8ffe2740 means Port already in use. It would have been nice if they had just supplied a simple explanation in there error message. Is that too much to ask for?

Nice Experience !!

Posted over 7 years back at Ajax on Rails


My first Barcamp was really a nice experience. Enjoyed some interesting sessions and some of them were riling me out.
But in all i can say it was good to be there and i will try to attend the all of them in the future.

Searchable RoR Docs

Posted over 7 years back at zerosum dirt(nap) - Home

One of the great things about PHP isn’t the documentation, per se, but rather the centralized, searchable docs interface at PHP.net. Big thanks to Jeremy Durham for putting together an equivalent Rails resource site. There’s obviously still a good bit of work to do before docs are as complete and usable as they could be, but an online searchable repository like this is definitely a step in the right direction. Bookmark it, and add some example code and comments mang.

Oh and while we’re talking about documentation (or lack thereof), don’t forget to donate to the Rails API docs project at Caboo.se if you haven’t already.

Going to BarcampDelhi-2

Posted over 7 years back at Ajax on Rails


BarcampDelhi-2 is all set to create a nice geeky happening on 9th december 2006. I am luckily attending the camp and the bar.
Barcamp is all about sharing new thoughts, discussing new technologies, talking web standards.
This time it is supposed to be rich in ruby and rails as rails is really booming everywhere.
I was even planning to give a presentation on Meta Programming in Ruby but at the moment the idea is in shade as we thought that the people there might not be as comfortable with ruby to pick the meta programming things interesting. So, now i have planned to present it somewhere in the ruby/rails workshop kinda meetups.

vicruby.com - Victoria Ruby Users Group

Posted over 7 years back at Eric Goodwin

I was talking with Mat Harvard on gtalk last night and the idea of starting a Victoria Ruby Users Group came up. I had bought vicruby.com quite a while ago but hadn't had the time to develop it so I quickly whipped up a template for stikipad, changed my DNS and we now have a wiki for the newly formed 'Victoria Ruby Users Group'. We'll see how it goes. Not sure what the interest is going to be like in Victoria. It's not that big of a place. Hopefully we will have our first meeting in the new year. Talk/presentation ideas anyone?

vicruby.com - Victoria Ruby Users Group

Posted over 7 years back at Eric Goodwin

I was talking with Mat Harvard on gtalk last night and the idea of starting a Victoria Ruby Users Group came up. I had bought vicruby.com quite a while ago but hadn't had the time to develop it so I quickly whipped up a template for stikipad, changed my DNS and we now have a wiki for the newly formed 'Victoria Ruby Users Group'. We'll see how it goes. Not sure what the interest is going to be like in Victoria. It's not that big of a place. Hopefully we will have our first meeting in the new year. Talk/presentation ideas anyone?

JavaScript Tricks (RJS-R): Cleaning Up My Mess...

Posted over 7 years back at zerosum dirt(nap) - Home

So a couple folks have pointed out that the last Rails+YUI example I posted doesn’t work in IE. Or Safari. Eek, that’s not so good.

Anyway, this post is kind of a hodgepodge documenting the process I went through to fix those issues and clean it up a bit. Maybe more of a ‘note to self’ than an actual blog entry, so not required reading by any means. Unless you’re having issues with IE and Minus MOR that is, in which case the magic word is content-type. I’m embarassed to say how much sleep I lost tracking that one down. Sigh.

class ExampleController < ApplicationController
  layout "standard", :except => :add

  def show
  end

  def add
    @response.headers['content-type'] = 'text/javascript';
    @thing = params[:thing]
  end
end

That’s our updated ExampleController. Notice that we’re setting the content type of the response in the headers now. The default content type appears to be html, instead of text/javascript. Not entirely sure why this is happening at the moment as Minus-R appears to set the content-type in it’s render method. But anyway, for whatever reason, Safari and Firefox both work fine, but IE doesn’t like it one bit. Of course, instead of warning us (or giving us an option to warn us, for that matter) it simply discards the asynchronous response. Hence, we never see an update. Nice, eh?

I also took the opportunity clean up the rest of our example a little bit. Here’s our new layout template:

<html>
<head>
  <title>YUI Tester: <%= controller.action_name %></title>
  <%= javascript_include_tag "yui/yahoo", "yui/event", "yui/dom", "yui/dragdrop", "yui/connection", "yui/container"%>
  <%= stylesheet_link_tag  'yui/container'%>

  <script language="javascript">
    YAHOO.namespace("yuitest.container");

    function init() {
      var handleCancel = function() { this.cancel(); };
      var handleSubmit = function() { this.submit(); };
      var handleFailure = function(o) { alert("failure: " + o.responseText); };
      var handleSuccess = function(o) { eval(o.responseText); };

      YAHOO.yuitest.container.myDialog = new YAHOO.widget.Dialog("myDialog", {
        width: "500px",
        modal: true, 
        visible: false,
        fixedcenter: true, 
        constraintoviewport: true, 
        draggable: true });

      var escKeyListener = new YAHOO.util.KeyListener(document, { keys : 27 }, 
        {fn:handleCancel,scope:YAHOO.yuitest.container.myDialog,correctScope:true} );

      YAHOO.util.Event.addListener( 'myDialogForm', 'submit', function(e) {
        YAHOO.util.Event.preventDefault(e);
        YAHOO.yuitest.container.myDialog.submit();
      });
        
      YAHOO.yuitest.container.myDialog.cfg.queueProperty("keylisteners", escKeyListener);
      YAHOO.yuitest.container.myDialog.cfg.queueProperty("buttons",
        [{ text:"Save", handler:handleSubmit, isDefault:true },{ text:"Cancel", handler:handleCancel } ]);

      YAHOO.yuitest.container.myDialog.callback = {
        success: handleSuccess,
        failure: handleFailure
      };

      YAHOO.yuitest.container.myDialog.render();
    }

    function addThing() {
      YAHOO.yuitest.container.myDialog.show();
    }

    YAHOO.util.Event.addListener(window, "load", init);
  </script>
</head>
<body>
  <div id="main">
    <% if flash[:notice] -%>
      <div id="notice"><%= flash[:notice] %></div>
    <% end -%>
    <%= @content_for_layout %>
  </div>
</body>
</html>

OK, a bunch of changes there. First, we’ve removed all the Prototype JS libs because we no longer need it — YUI’s connection manager can take care of this stuff for us, and since we’re not using the default behavior of RJS, there are no worries about dependence on Prototype. Next, we’ve added a couple key listeners on the popup dialog to handle enter (submit) and escape (cancel). Note that we have to use Event.preventDefault() in our enter key listener to suppress the default form submission action. Otherwise, we end up redirected to a new page that just contains our result string, and we don’t want that…

Finally, we’ve also eliminated the clumsy body of the success handler and replaced it with a single statement: eval(o.responseText). Yup, we can just evaluate the JavaScript returned from our Rails app. No need to append a new script tag to the body, yehck. Here’s the code that’s returned from our add.ejs template, as a reminder (it’s unchanged):

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

So yeah, it just replaces the inner HTML in the element named hello_msg. Easy enough. The next step here would be to figure out how to encapsulate the stuff in the layout using some sort of helper module or plugin. But that’s it for now.

(Progress on my current Rails project has been pretty slow lately, as we’re nearing completion on a big client project (a slick Java-based webstart app that’s been occupying the majority of my time for the past 6 or so months). It’s nice to finally see the light at the end of the tunnel! Hopefully once that wraps, we’ll have some significant time to pour into the RoR ideas and prototypes we’ve been playing around with…)

Multiple Concurrent Database Connections with ActiveRecord

Posted over 7 years back at schadenfreude

ActiveRecord is a great tool to use for database maintenance as I explored in my previous article, Using ActiveRecord for Simple Maintenance Scripting, but what if you need to do tasks that require you to be connected to multiple databases at once.

Perhaps you want to compare records in one database and copy them to another, well heres how you do it.

Multiple Concurrent Database Connections with ActiveRecord

Posted over 7 years back at schadenfreude

ActiveRecord is a great tool to use for database maintenance as I explored in my previous article, Using ActiveRecord for Simple Maintenance Scripting, but what if you need to do tasks that require you to be connected to multiple databases at once.

Perhaps you want to compare records in one database and copy them to another, well heres how you do it.

Multiple Concurrent Database Connections with ActiveRecord

Posted over 7 years back at schadenfreude

ActiveRecord is a great tool to use for database maintenance as I explored in my previous article, Using ActiveRecord for Simple Maintenance Scripting, but what if you need to do tasks that require you to be connected to multiple databases at once.

Perhaps you want to compare records in one database and copy them to another, well heres how you do it.

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? :-)