What we're listening to:
Jared

The Hold Steady:
Heaven Is Whenever
Jeff

Paper Route:
Absence

For adding a blog to your refinery site, there’s pretty much only one option: the refinerycms-blog plugin. Fortunately like most refinery things, it’s pretty easy to customize.

I wanted to use DISQUS to moderate the comments on this particular blog, and here’s how I did it (You obviously need a DISQUS account to do this).  If a file referred to doesn’t exist, copy it from vendor/plugins/app/views/blogs to your theme directory.

  1. Remove the old comment form:
    themes/mysite/views/blogs/show.html.erb

    remove the render “_form” line since we don’t need a comment form anymore
  2. Add the Disqus embed code
    themes/mytheme/views/blogs/_comments.html.erb

    Replace everything in this file with the disqus embed code, replace mysite below with your disqus shortname.

    <div id='comments'>
     <div id="disqus_thread"></div>
     <script type="text/javascript">
     var disqus_identifier = "<%= @blog.permalink %>";
     <%= "var disqus_developer = 1;" if local_request? %>
    
     (function() {
     var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
     dsq.src = 'http://mysite.disqus.com/embed.js';
     (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
     })();
     </script>
     <noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript=mysite">comments powered by Disqus.</a></noscript>
    </div>
  3. Add the disqus comment counter code
    /themes/mysite/views/blogs/index.html.erb

    Change line 16 to:

      <%= link_to 'Read more', blog_post_url(blog.permalink)+"#disqus_thread" -%>
    

    Put this somewhere near the bottom:

    <% content_for :footer do -%>
     <script type="text/javascript">
     //<![CDATA[
     (function() {
     var links = document.getElementsByTagName('a');
     var query = '?';
     for(var i = 0; i < links.length; i++) {
     if(links[i].href.indexOf('#disqus_thread') >= 0) {
     query += 'url' + i + '=' + encodeURIComponent(links[i].href) + '&';
     }
     }
     document.write('<script charset="utf-8" type="text/javascript" src="http://disqus.com/forums/poetrybooths/get_num_replies.js' + query + '"></' + 'script>');
     })();
     //]]>
     </script>
    <% end -%>

    /themes/mysite/views/shared/_footer.html.erb
    add <%= yield :footer %> to your footer file so our comment counter javascript gets placed there.

Pretty easy.

Recently I’ve been evaluating refinerycms for a few client projects that it seemed suited for, and I really like that while it’s not always 100% what I want, it’s very easy to modify to get it to where I need it.

Here’s an example: My site needs a main nav to link offsite in a new window by adding target=”_blank” to the link, which is not handled out of the box by refinery.  So I copied vendor/refinery/app/views/shared/_menu_branch.html.erb into my theme directory to override the functionality and modified line 11 to the following:

<%= link_to menu_branch.title, menu_branch.url, \
:target => menu_branch.url.include?("http://") ? "_blank" : "" %>

Now any link containing http:// is automatically given a blank target. Presto.

I’m liking paperclip, in a recent project I chose it specifically because it buffers writes on uploads, which should help keep memory usage down.

I needed to validate that an uploaded image was at least a certian size, and it was a little tricky, but here’s what I came up with:

 has_attached_file :image,
                   :styles => { :original => ["1000x600>", :jpg]},
                   :whiny_thumbnails => true

 def validate
    dimensions = Paperclip::Geometry.from_file(self.image.queued_for_write[:original])
    self.errors.add(:image, "Please upload a file at least 700 pixels wide") if dimensions.width < 700
    self.errors.add(:image, "Please upload a file at least 200 pixels tall") if dimensions.height < 200
  end

like it? hate it? have something better?

rspec+rcov = segfault death

November 14th, 2008

I was pounding my head against the keyboard. Rspec with rcov was crashing whenever it felt like it. I was getting all kinds of errors like:

/opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/matchers/be.rb:92: [BUG] rb_gc_mark(): unknown data type 0×0(0×489ffc8) non object
ruby 1.8.6 (2007-09-24) [i686-darwin9.3.0]

opt/local/lib/ruby/gems/1.8/gems/rspec-1.1.11/lib/spec/example/example_group_methods.rb:344: [BUG] Segmentation fault
ruby 1.8.6 (2007-09-24) [i686-darwin9.3.0]

not to mention a bus error or two as well.

Then I found this article with this solution:

$ gem sources -a http://gems.github.com (you only have to do this once)
$ sudo gem install mergulhao-rcov

from this guy.

Then the world was right again.

Today, I got bit by ActiveRecord race condition related to validates_uniqueness_of. Sometimes I just blindly trust that Rails is going to take care of things, and so it surprised me when I ended up with duplicate records in my database. A few people have written about this, and apparently it’s in the API Docs now, but I just hadn’t thought about it before.

The solution looks to be enforcing unique constraints at the database level.

By default I include the rails t.timestamps in my create table migrations. Always nice to know when a model has been created or updated, right? And what could it hurt?

Well, when they are in a join table for a habtm relationship they cause the associated records to be marked as readonly. This is because rails can’t save those extra timestamp attributes.

If timestamps or any other extra join information is needed, then use a join model instead with has_many :through.

more info

exception_notifier gotcha

July 22nd, 2008

Yesterday I was investigating why exception_notifier wasn’t, well, notifying me of exceptions.

I checked out the log, and I was getting an error like this:

ActionView::TemplateError (protected method `filter_parameters' called for #<Admin::ProductsController:0x2aaaaeccd6b0>)

Turns out Rails 2.1 breaks the version of exception notifier you get by running script/plugin install exception_notifier. To get the correct version, you have to run script/plugin install git://github.com/rails/exception_notification.git

Pretty lame, they really should update that.

form_builder tip

June 16th, 2008

I ran into a situation this week where I had a single partial containing form fields being rendered for different models. Inside that partial, one of the fields was a text_field_with_autocomplete, which presented a problem, since form_builder doesn’t know anything about text_field_with auto_complete, and the text field certainly needed to know what model we were working with here. After a little digging, turns out form_builder exposes a getter called object_name:

<%= text_field_with_auto_complete f.object_name, :city_name, ... %>

Easy.