07 Nov, 2007

Published at 01:24PM

Tagged with calendar, design, javascript, mootools, and web

This post has 4 comments

MooMonth calendar

Here’s an interesting approach for displaying calendar events: MooMonth calendar. And here’s a demo to see it in action (make sure you click on a date twice).

It’d have to be on an app that had intense event-scheduling to alleviate the fact that a full-screen calendar might be an overkill solution. Still pretty cool, though. It makes me want to build something with a calendar.

06 Nov, 2007

Published at 05:33PM

Tagged with forms, programming, rails, and tips

This post has 0 comments

Updating multi-model forms in Rails

The other day I received an email about the post concerning multi-model forms in Rails. This person had a similar situation, but was having difficulty saving the records on an update. I didn’t make that part very clear, so I figured I’d complete the puzzle.

If you recall, there was a check in the set_model_attributes method that looks for an id (attributes[:id].blank?) so it’d know whether it was supposed to update or create. If there’s an id present, it must be an update.

Based on these two lines,

1
2
_model = send(model).detect {|m| m.id == attributes[:id].to_i}
_model.attributes = attributes

there’s a misconception that the model’s attributes are getting saved. Setting the attributes like this does not save them, but it’s easy to do. I’m using an after_update callback which looks like this:

1
2
3
4
5
6
7
8
9
10
class Course < ActiveRecord::Base

  has_many :holes, :dependent => :destroy
  has_many :tees,  :dependent => :destroy  

  after_update { |c| c.save_associated :holes, :tees }

  # ...

end

And the save_associated method looks like this:

1
2
3
4
5
6
7
8
9
10
def save_associated(*models)
  models.each do |model|
    send(model).each do |attributes|
      # handle validations before this point
      # and pass false to the save method to
      # ensure that the attributes get saved
      attributes.save(false)
    end
  end
end

If you’re only dealing with one association you can eliminate the parameters and the nested loop, as well as provide a more meaningful method name for the callback (such as save_holes). All in all, this seems to work pretty good.

Chris mentioned conductors in an earlier comment, which also seems like a viable option.

04 Nov, 2007

Published at 02:24PM

Tagged with programming, rails, and tips

This post has 0 comments

Textilizing multiple fields at once

Textile is awesome. So awesome, in fact, that I use it on just about every text area of every Rails application I build. In the database I typically have a field for the raw text and a field for the marked-up, textilized text (one for editing, one for displaying). And up until recently I’ve only had at most one field per model that needed to be “textilized.” Well the helper I was using will no longer suffice, so I’ve implemented a new version. It’s now a class method and can accept multiple columns at once, as well as a column suffix (defaults to _html). Here’s how it works:

1
2
3
4
5
6
7
8
# Implied DB columns:
# - notes,       notes_html
# - description, description_html
# - summary,     summary_html

class FilledWithText < ActiveRecord::Base
  textilize :notes, :description, :summary
end

However, if there is some sort of conflict or need to have the columns be something other than [column]_html, you can just pass the suffix as a key/value pair at the end of the parameter list. Also, you can give the key any name you’d like for readability sake—it only really cares about the value…

1
2
3
4
5
6
7
8
9
# Implied DB columns:
# - about,   about_source
# - article, article_source

class MoreText < ActiveRecord::Base
  textilize :about, :article, :suffix => 'source'
  # or
  textilize :about, :article, :ending_of_textilized_columns => 'source'
end

It’s been quite handy for me so far. I’m sure the implementation isn’t perfect, but here’s what I came up with:

1
2
3
4
5
6
7
8
9
10
11
12
13
def textilize(*columns)
  methods = []
  suffix  = columns.last.is_a?(Hash) ? columns.pop.values.last : 'html'

  columns.each do |column|
    define_method "#{column}_to_html" do
      self["#{column}_#{suffix}"] = RedCloth.new(self[column] || '').to_html
    end
    methods << "#{column}_to_html".to_sym
  end

  before_save *methods
end

If you use textile, it’s worth doing something like this, as it makes it so much easier to convert and self-document textilized columns. Just stick it in a module to use across all of your models.

Of course, after the fact I realized there was a much better solution. I should have known to check first. Oh well, it’s still good for me to cook my own soup, so to speak.

01 Nov, 2007

Published at 07:51PM

Tagged with forms, programming, rails, and tips

This post has 5 comments

Handling multi-model forms in Rails

Sometimes (a lot of times, actually) I need to post a form that deals with several different models. For instance, in Golf Trac, fields_for "course[course_holes][]" passes an array of hole attributes that relate back to a course, where a course has_many holes. A course also has_many tees, so there’s a fields_for "course[course_tees][]", as well. This post isn’t about how to setup the forms, but more of what to do in the model.

Of course, I’m sure there are a lot of different ways to do this, but here’s my approach:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Course < ActiveRecord::Base

  has_many :holes, :dependent => :destroy
  has_many :tees,  :dependent => :destroy

  def course_holes=(course_holes)
    set_model_attributes(:holes, course_holes)     
  end

  def course_tees=(course_tees)
    set_model_attributes(:tees, course_tees)
  end

  private

  def set_model_attributes(model, model_attributes)
    model_attributes.each_with_index do |attributes, index|
      if attributes[:id].blank?
        send(model).build(attributes)
      else
        _model = send(model).detect {|m| m.id == attributes[:id].to_i}
        _model.attributes = attributes
      end
    end
  end

end

I’m going to need the set_model_attributes method in a few other places, so it’ll eventually end up in a module.

31 Oct, 2007

Published at 06:05AM

Tagged with photography

This post has 0 comments

The Joby Gorillapod is incredible

The Gorillapod is the best thing I’ve purchased in the last six months. If you’ve taken shots with long exposures, you know how important it is to have a steady hand. Even a brain surgeon couldn’t hold a camera still enough to take crisp long exposures. So that means a tripod is needed. I have a nice one, but I don’t always feel like lugging it around. Lately I’ve just been carrying the Gorillapod with me, and it works as advertised. It will wrap and hold very still onto anything it can get a grip on.

Fork out the $60 or whatever it is. If you’re into photography at all, it’s a must-have in my humble opinion. (Note: there are two versions, one for DSLRs and one for point-and-shoots, so the weight capacities are different… make sure you pay attention when purchasing)

29 Oct, 2007

Published at 05:50PM

Tagged with gems, programming, rails, ruby, site, and syntax

This post has 0 comments

Upgraded syntax highlighting

I’ve been wanting to upgrade the syntax highlighting on this site for some time now. It’s perfect for Ruby, but it lacks support for other languages. Particularly, though, Rails’ view code looks horrible. It parses everything between the slashes, <td/>...</tr> for example, as a regex.

the solution

Enter Ultraviolet. To quote the site, “it is able to produce html output for all the syntaxes in Textmate’s repository.” Which is a ton. It also supports themes, line numbers, and has xhtml output. Here are a couple of examples…

1
2
3
4
5
6
7
# xhtml output for Ruby on Rails, 
# with line numbers, using the blackboard theme:
html = Uv.parse(text, "xhtml", "ruby_on_rails", true, "blackboard")

# xhtml output for ERB (view) templates in Rails, 
# without line numbers, using the sunburst theme:
html = Uv.parse(text, "xhtml", "html_rails", false, "sunburst")

It’s pretty cool. Chris was kind enough to show his implementation for syntax highlighting, but I needed to make a minor modification to the regexp to support code.[language] instead of only code.ruby. Here’s the Ultraviolet version:

1
2
3
4
5
6
7
8
9
require 'uv'

def colorize_code
  r = RedCloth.new(self[:body] || '')
  self[:body_html] = r.gsub(/<code.(\w+)>\s(.*?)<\/code.\1>/m) do
    lang, code = $1, $2
    html = "<notextile>" + Uv.parse(code, "xhtml", lang, true, "sunburst") + "</notextile>"
  end.to_html
end

I enjoy the line numbers, but by default they’re included with each line of code—to copy and paste means to remove each line number. If you care about that, here’s a way to create your own line numbers so that the code and line numbers are separated.

1
2
3
4
5
6
7
8
9
10
11
12
require 'uv'

def colorize_code
  r = RedCloth.new(self[:body] || '')
  self[:body_html] = r.gsub(/<code.(\w+)>\s(.*?)<\/code.\1>/m) do
    lang, code = $1, $2
    html   =  Uv.parse(code, "xhtml", lang, false, "sunburst")
    result =  "<notextile><pre class=\"lines\">"
    result << (1..code.split("\n").size).to_a.join("\n")
    result << "</pre>#{ html }</notextile>"
  end.to_html
end

Then just do a float:left; on the .lines CSS class, and viola, your line numbers are separate from your code. There’s one more thing to make note of, though. As horrible as this sounds, you may want to use an inline style on the pre tag in place of the CSS class. The reason is because of how the code will look when it goes out to an RSS reader. What it’s doing is putting an extra pre block with just the line numbers above your code, but the CSS makes it appear beside it. Personally, I found style="float:left;padding-left:10px;" to work well.

ultraviolet in production

So the implementation is pretty easy, but here’s where things get difficult and very annoying. This is also why I’m not currently using Ultraviolet (in production) yet. You see, Ultraviolet indirectly requires the use of the (what is supposed to incredible) Oniguruma regular expression library, which isn’t packaged with Ruby until Ruby 1.9 (but is available as a gem).

I installed the gem without any problems on my machine; however, I could not for the life of me get it working on DreamHost. I freeze my gems, but the problem is that it had to be installed and frozen from the server and not my local machine. Since I’m on Windows (blah) in development, the oregexp.c file was compiled for an mswin32 environment, which is not the case in production. Apparently that matters. I have very little experience modifying environment variables and .bash_profile and all the other jazz I found online, so I was a little timid to go further than I’d be able to fix.

unfortunate conclusions

After a couple (or few?) hours of hacking at things I didn’t really know how to hack, I ended up back at the beginning: using the plain old syntax gem. What a great feeling it is to waste hours of my personal time.

I considered extending the syntax library to satisfy me for the time being (mainly for view templates), but I haven’t decided yet if I want to get into that or not. But definitely not today. I’m burnt out on syntax highlighting.

In the end, Ultraviolet is an awesome syntax highlighting library, and you should think about using it. Unfortunately for me, I was unable to get it working on DreamHost thanks to Oniguruma, but maybe (if you actually know what you’re doing) it’ll go better for you. Good luck!

28 Oct, 2007

Published at 05:14PM

Tagged with golftrac, helpers, programming, and rails

This post has 0 comments

Refactored block helper

Sometimes when I post about something, I think more about what I’m doing, which in turn helps me to realize a potentially better solution. For instance, before I had i<2 ? true : false which is the same as i < 2—what was I thinking??? Anyway, the problem now is I don’t know if I’m taking this simple thing too far. The block helper I was using is:

1
2
3
4
5
6
def handicaps_and_pars(&block)
  titles = ["Men's Handicap", "Men's Par", "Ladies' Handicap", "Ladies' Par"]
  4.times do |i|
    yield titles[i], i % 2 == 0 ? 'handicap' : 'hole', i < 2 ? true : false
  end
end

I pulled out the parts that made my brain work a little harder into a separate method that returns the yielded data as an array:

1
2
3
4
def data_for_index(index)
  titles = ["Men's Handicap", "Men's Par", "Ladies' Handicap", "Ladies' Par"]
  [titles[index], index % 2 == 0 ? 'handicap' : 'hole', index < 2]
end

And from that I was between two options…

1
2
3
4
5
6
7
8
9
10
11
12
# option 1 - separate data into meaningful variables
def handicaps_and_pars(&block)
  4.times do |i|
    title, partial, is_mens = data_for_index(i)
    yield title, partial, is_mens
  end
end

# option 2 - yield the method itself
def handicaps_and_pars(&block)
  4.times { |i| yield data_for_index(i) }
end

I decided to go with option 2, as I think it’s the more concise of the two. But maybe I took this already short method too far? Sometimes I don’t know when to stop with this stuff, but it’s still fun to explore the options.

28 Oct, 2007

Published at 03:01PM

Tagged with golftrac, programming, and rails

This post has 3 comments

Nothing like a good block helper

I took a few months leave of absence from Golf Trac. Well, the other evening I decided to go through the entire application and clean out the garbage (I had a feeling there’d be some). I forgot how surprisingly complex it was to model a golf scorecard with a normalized database and a single web form. But that’s not the point. The point is I love blocks in Ruby, particularly block helpers.

One of the things I came across was this _handicaps_and_pars.rhtml partial:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<tbody id="holes-<%= side %>">    
  <tr>
    <td>Holes</td>
    <%= hole_count_for(side) -%>
  </tr>
  <tr>
    <td>Men's Handicap</td>
    <%= render :partial => 'handicap', :collection => @course.holes, :locals => { :mens => true, :side => side } -%>
  </tr>
  <tr>
    <td>Men's Par</td>
    <%= render :partial => 'hole', :collection => @course.holes, :locals => { :mens => true, :side => side } -%>
  </tr>
  <tr>
    <td>Ladie's Handicap</td>
    <%= render :partial => 'handicap', :collection => @course.holes, :locals => { :mens => false, :side => side } -%>
  </tr>
  <tr>
    <td>Ladie's Par</td>
    <%= render :partial => 'hole', :collection => @course.holes, :locals => { :mens => false, :side => side } -%>
  </tr>
</tbody>

It’s actually not that bad because it reveals what’s going on quite nicely. But there are just too many commonalities to leave it alone (the tr’s, td’s, :collection, :side, etc), so I added this little helper to assist with the problem:

1
2
3
4
5
6
def handicaps_and_pars(&block)
  titles = ["Men's Handicap", "Men's Par", "Ladies' Handicap", "Ladies' Par"]
  4.times do |i|
    yield titles[i], i % 2 == 0 ? 'handicap' : 'hole', i < 2 ? true : false
  end
end

And now the partial looks a little cleaner:

1
2
3
4
5
6
7
8
9
10
11
12
<tbody id="holes-<%= side %>">    
  <tr>
    <td>Holes</td>
      <%= hole_count_for(side) -%>
  </tr>
  <% handicaps_and_pars do |title, partial, is_mens| %>
    <tr>
      <td><%= title -%></td>
      <%= render :partial => partial, :collection => @course.holes, :locals => { :mens => is_mens, :side => side } -%>
    </tr>
  <% end -%>
</tbody>

I could probably make the helper a bit more readable…

1
2
3
# inside the 4.times block
title, partial, is_mens = titles[i], i % 2 == 0 ? 'handicap' : 'hole', i < 2 ? true : false
yield title, partial, is_mens

...but I doubt that I will, considering I’m the only one working on the code.

I suppose another thing that would make the view more appealing would be to use Markaby (or something similar)... those <%= -%> tags are beginning to annoy me.

25 Oct, 2007

Published at 04:28AM

Tagged with plugin, programming, and rails

This post has 3 comments

Scoping out a model

That didn’t come out right. What I meant to say was there is a great new Rails plugin called scope_out that assists with AR class methods, and you should try it out.

First of all, you shouldn’t have something like Whatever.find(:all, :conditions => 'something IS NOT NULL') in your controllers. That find should be put into the model ( Whatever.find_something instead). Well, scope_out makes that process a little nicer.

I’ll use Golf Trac as an example. So, in Golf Trac, there are 9 hole and 18 hole courses all over the place. At some point, I may want to show a list of each, independent of the other. Here’s what I might do normally:

1
2
3
4
5
6
7
8
9
class Course < ActiveRecord::Base
  def self.find_nine
    find(:all, :conditions => ['is_eighteen = ?', false])
  end

  def self.find_eighteen
    find(:all, :conditions => ['is_eighteen = ?', true])
  end
end

I definitely can’t complain about that, but there’s an even nicer way. Let’s look at how scope_out can help…

1
2
3
4
class Course < ActiveRecord::Base
  scope_out :nine,     :conditions => { :is_eighteen => false }
  scope_out :eighteen, :conditions => { :is_eighteen => true  }
end

That’s pretty cool. That allows Course.find_nine and Course.find_eighteen just like the regular class method implementation. It creates methods with find_ appended to whatever you’re “scoping out.” Another nice thing about it is you can still pass in additional options to the finder.

1
2
Course.find_nine(:first)
Course.find_eighteen(:all, :order => 'created_at DESC')

It also allows the ability to use it in a “with_scope” fashion. For instance…

1
2
3
4
Course.with_eighteen do
  @recent = Course.find(:order => 'created_at DESC', :limit => 5)
end
# => five most recent eighteen hole courses

Dynamic finders also come as a bonus with this plugin. So find_all_by_whatever now has a cousin or two, find_all_nine_by_whatever and find_all_eighteen_by_whatever.

That’s great and all, but the more typical case would be what nine hole and eighteen hole courses a user has. Well, since scope_out works with associations, too, it’s not a problem:

1
2
3
4
5
current_user.courses.find_nine
# => all nine hole courses this user has added

current_user.courses.find_eighteen
# => all eighteen hole courses this user has added

There are a few other cool things this plugin supports. If you can look beyond the fact that this doesn’t make any sense, you can see how combining two scopes is done:

1
2
3
4
5
class Course < ActiveRecord::Base
  scope_out :nine,     :conditions => [ 'is_eighteen = ?', false ]
  scope_out :eighteen, :conditions => [ 'is_eighteen = ?', true  ]  
  combined_scope :both, [:nine, :eighteen]
end

Again, that’s dumb. Course.both is the same as Course.find_all since it’s a boolean condition, but you get the idea. To install with_scope:

script/plugin install http://scope-out-rails.googlecode.com/svn/trunk/

That will put a “trunk” folder in your plugins directory, which you should rename. Enjoy.

24 Oct, 2007

Published at 04:55AM

Tagged with browsers, css, design, hacks, tips, and web

This post has 0 comments

CSS hacks

CSS alone is great, but CSS plus standard browser support would be even better. Unfortunately, I doubt that will ever happen, so we hack. I’ve finally limited my browser concerns to the following four: Firefox, Safari, IE7, and IE6 (with IE6 slowly dropping off the list).

As I’m sure you already know, the problem is mainly IE. I had high hopes for IE7, but I have to accommodate it, too. Before IE7 I used the * html hack (or “holy hack” as they call it) for my IE fixes. Since IE7 behaves differently than IE6, but is still not right, I need to attack it as a separate entity. I personally believe conditional comments to be the best alternative for this. It’s ugly, but most hacks are.

Here’s the top of (most of) the sites I build…

<link href="/stylesheets/default.css" media="screen" rel="stylesheet" type="text/css" />
<link href="/stylesheets/safari.css" media="screen" rel="stylesheeet" type="text/css" />
<!--[if IE 7]>
<link href="/stylesheets/ie7.css" media="screen" rel="stylesheet" type="text/css" />    
<![endif]-->
<!--[if IE 6]>    
<link href="/stylesheets/ie6.css" media="screen" rel="stylesheet" type="text/css" />
<![endif]-->

It’s important to note the order, too. Always put the default styles at the top, then override them with the hacks. Oh, and in the safari.css file, just make sure your styles look like this:

/*\*/
html*ul#content-nav {
  top: 128px;
}
.
.
.
html*div#sidebar {
  margin-left: -10px;
}
/**/

And remember, in order to override behavior you have to define the selector the same way in your hacks file as it were in the default file due to specificity (ie if you have div p.errors in the default file, you can’t expect p.errors to override it since the latter has a lower specificity).

If you have other suggestions, I’m always interested in better ways to hack CSS.

19 Oct, 2007

Published at 04:39AM

Tagged with flickr, personal, photography, photos, and statistics

This post has 0 comments

10,000 views on Flickr

Since I have some sort of obsession with patterns and data, I’m going to time stamp the day my photos reached 10,000 views. Before the Nikon, I had around 1,800 views of about 1,200 photos, and now it’s 10,000+ views of about 1,950 photos. That’s a 727% increase (1.5 views/photo to 10.9 views/photo).

OK, I’m done.

16 Oct, 2007

Published at 06:11AM

Tagged with programming and ruby

This post has 0 comments

Ruby inheritance quiz

If you’re interested, here’s a quick Ruby inheritance quiz.

For some, I think the point of confusion would relate to the metaclass. This is how I understand it to work: it inserts a “virtual” class between the object and its real class, which makes the original class the superclass (or parent?), and the metaclass becomes the objects’ direct class for that instance. So the identify method hits the metaclass first because it was inserted (or attached to the object) after the object was created, and squeezed in before the Child class in the hierarchy. That’s why it [the metaclass] is able to intercept the call. I think, anyway.

Ruby is slick, readable, and fun to program, but it can be quite complex at times. If you didn’t get the “quiz” correct, stop now and learn why it works that way—it will save you troubleshooting time and make you a better Ruby programmer altogether.

12 Oct, 2007

Published at 04:32AM

Tagged with browsers, javascript, and web

This post has 0 comments

Advanced browser detection script

Anymore, it seems like I’m always mixing in some custom javascript when building out a user interface. Unfortunately, though, not all browsers respond the same way, so it’s important to know which browser is running the scripts in order to accommodate those users. I can’t say that I’ve looked into it that much, but as far as browser detection scripts go, this one is the best I’ve used. What I particularly like about it is its ability to reveal which version (read: IE6 or IE7?) of which browser is being used.

I don’t know when I’ll start ignoring IE6. Life as a web developer would be so much easier. I always say I’m going to, but when it comes time, I can’t walk the walk.

11 Oct, 2007

Published at 05:04AM

Tagged with css, design, inspiration, and web

This post has 0 comments

A few more well-designed sites

A few designs I found appealing, in no particular order…

  • http://www.cabedge.com/—Extremely plain, but well suited for what it is. It’s hard to miss the floating clouds and isolated introduction paragraph, which was obviously their intention.
  • http://jinabolton.com/—This one is for the logo pretty much… I think it [the logo] is awesome.
  • http://oaktreecreative.com/—All around great design. I love the white strip through the middle. And while it’s somewhat of a trend, I’m partial to the “one concise sentence to explain what we do” idea.
  • http://www.rikcatindustries.com/—It’s a common misconception that color is required for art/designs to be appealing, but I think this site proves otherwise (as does black & white photography).
  • http://www.blogonize.com/—It sort of has that “blogger” feel to it, which in a way gets old, but in a way is still nice.
  • http://www.positionlab.co.uk/—The upper half of this site is what draws me in. The colors blend well and it’s kind of cool that they used a topographic map background to play off of their slogan. Simple and clean always works.
  • http://9rules.com/—I love the 9rules leaf. I don’t really think of 9rules as a social network, but I guess it is. Anyway, I enjoy the main page design.
  • http://www.turncolor.com/—This is another case of brown and blue and how well it works. There’s hardly anything to this site, but I think it’s a perfect blend of color. I love the “scratchiness” of the header, and the contact form is awesome. It’s hard to believe brown can be so inspirational.

UPDATE

08 Oct, 2007

Published at 07:45PM

Tagged with personal, rails, reflection, rest, and web

This post has 3 comments

Finally, some REST

No, not the “why do you insist on no more than 5 hours of sleep” kind, but the resource representation kind. Here’s part of a post I read a few days ago:

If I had to choose the single most not-really-well-understood, mystified, unsuccessfully demystified, explained and still not-really-grasped topic in the Rails world (and beyond), my vote would definitely go to REST.

Maybe it’s not quite that bad, but there does seem to be a bit of clarity missing as to why it’s all the rage. I understand some of it, but I think I’m missing most of it. Although, I’ve yet to actually use it. I know it’s been around for quite a while now, but… well… I have no excuses; no real excuses. My shallow excuse would have to be laziness. I’ve been far too lazy the past few months (or year?) to convert a single existing application to REST. And to be honest, aside from laziness, I can’t say that I completely understand the point.

I’m aware of how nice it is for API development, but if there isn’t an exposed API involved, is it really worth it? Is it the clean(er) URLs? The true HTTP caching? A better convention? Nicer routes.rb file? More focused controllers? (Supposedly) better application designs? All of the above?

That stuff is all well and good, but is that really what’s driving this force of RESTful architectures? It just seems like there’s something [bigger] I’m missing.

Regardless, I’ve put it off long enough. Now that Rails 2.0 is on its way, it’s time for me to stop making excuses. I need to get on board so I can realize why it’s so wonderful. Since the core team felt that it was a good thing to integrate REST directly into Rails, I’m sure it is; I just need to learn more about it.

So from here on out, all of my new applications will be RESTful, but I still don’t know that it’s worth converting existing applications. Who knows, though, maybe that’s easy to do.

Ryan Heath | Site Management A Ruby on Rails production.

This site is a Formed Function. Formed Function LLC | @formedfunction | Get in Touch