VisezTrance

  • May 1, 2012 6:12 PM

    Abstract naming conventions

    By Daniel - No Comments
    From time to time I get stumped - I just can't find a *good* name for a class, method or variable. Sometimes I search for synonyms online or ask a colleague for suggestions. However, the naming conventions used in rails makes things easier, yet they may not scale very well.

    For example, a polymorphic comment association is usually named commentable, whereas for an image - imageable. Simple enough, but the fact is that I actually ended up with names such as photoable, wallable and wizzardable (I kid you not).

    Right now I'm using parent, and it works great.

    belongs_to :parent, :polymorphic => true

    However, parent.parent.post is not as informative as imageable.commentable.post, but frankly this is hardly a problem. Based on this railscasts episode, I could get the current parent inside a controller by using the following:

    def find_commentable
      params.each do |name, value|
        if name =~ /(.+)_id$/
          return $1.classify.constantize.find(value)
        end
      end
      nil
    end

    Do this for images as well, and you'll probably see a pattern. So how about we just rewrite it in the application controller:

    def current_parent
      return @current_parent if @current_parent
      params.each do |name, value|
        if name =~ /(\w+)_id$/
          @current_parent = $1.classify.constantize.find(value)
          return @current_parent
        end
      end
      nil
    end

    So using parent actually makes sense.

    If your application gets large enough, or you need to fix a bug on an older project you'll probably notice one thing - you can't recall the column names. Was it name, subject, title or content, contents, description? This gets even worse if you haven't wrote that code in the first place. For more than a year, on the projects I've been working on (which have been quite a few) I decided on always sticking with name for single line descriptions (varchar) and contents for the ones with multiple lines (text). There may be other fields of course, but this worked out surprisingly well.

    It feels nice when a colleague writes the frontend and doesn't even need to look over the database schema.
  • October 6, 2011 7:55 PM

    Nodejs and coffeescript

    By Daniel - No Comments
    My first contact with nodejs was at Yahoo's open hack event that took place at Bucharest last spring. It was fun, however I just couldn't find the time to tinker with it as much as I would've liked to.

    Lately this changed, and I'm actually using it for a project we're developing at work where it fits the bill quite nicely. While I'm quite familiar with javascript I'm coding in coffeescript. Initially I was reluctant on using it especially as I'm not very found of indentation based languages, but as far as backend javascript developing goes, it's a god send.
    I think that the main reason I like it despite its flaws (it's just a wrapper after all) is that it almost forces good coding practices such as using short methods and avoiding deeply nested constructs.

    I'm using the emacs coffee mode extension to compile my coffee files to js on each save. I imagine that most major editors have similar extensions as well.

    Restarting node on each change can get a bit tiresome. To resolve this I'm using the supervisor plugin:

    npm install -g supervisor

    And instead of starting the application with node:

    supervisor -p server.js

    Basically the browser can now be refreshed on each coffee file change. Neat.
  • September 27, 2011 10:25 PM

    Sitemap

    By Daniel - No Comments
    I recently wrote a sitemap gem for one of the more larger sites I have been working on, which was recently revamped.

    To be fair I searched for existing solutions, but I found them lacking for one reason or another. One of the main problems that these plugins couldn't overcome was generating a different url (such as dynamic domains) based on an existing attribute.

    There are some limitations as well, most notably the 50.000 urls per sitemap, but I'm planning on resolving this issue some time in the near future.

    If you decide to test it I strongly believe that the docs cover the functionality pretty well. Additionally make sure using webmaster-tools that google bot can use your feed.
  • September 27, 2011 9:55 PM

    User names consistency

    By Daniel - No Comments
    Just as I don't like mixing tabs with spaces I hate it when people type in a form using their real name without any concern for capitalization.

    I could had certainly write a one liner that fixes this, but I recently started using the namecase gem which also provides some more interesting cases as well:

    NameCase("RON BURGUNDY")  # => Ron Burgundy
    NameCase("MCDONALDS")     # => McDonalds
  • March 19, 2011 11:55 AM

    Old wounds heal slow

    By Daniel - No Comments
    Internet Explorer 9 was recently launched and received an overwhelming amount of positive reviews as well as a nice welcome from the developer community.

    My thoughts about it remind me of a story I heard many years ago.

    A child's obnoxious behavior upsets his father on a daily basis. The afflicted parent would sometimes hammer a nail onto a door. After a while the curious child asked about the nails - "I've put a nail every time you made a bad deed", his father sorrowly answered. Later on, somewhat troubled, the child told his father "Look, I've thought about it and I don't want to upset you again, but for each day I behave you will take out a nail." The two were in agreement and as the days passed the parent would remove one nail after the other. One day the boy noticed that the nails were all gone. Happy, he called out his father "Look, I made it, the door doesn't have any more nails". "You're right", his father answered, "but what about the holes?"

    While it's really nice that IE is once again a good browser, it's just not going to give me back all the nights I lost hacking layouts for the better half of the last decade.
  • March 7, 2011 2:09 AM

    I'm done posting on StackOverflow

    By Daniel - No Comments
    I can honestly say that the main reason for helping others is selfishness, because you see there's a certain feeling of accomplishment when helping someone with an issue that eluded me as well.

    A few years ago I found my self spending quite some time on various forums. While it was mostly procrastinating I had the distinct feeling that I was actually contributing to something. After moving out from my parents house, on to the big city I met some very cool people, that had a lesser interest in an online presence and more of a hands on approach to tackle real problems. I was now reading the source code rather then browsing outdated blog posts.

    One day, having a project with a tighter deadline and a long commute I was working from the comfort of my home trying to finish up. I was almost there, just needed to implement a pure javascript survey module by detecting the most common element in an array. Not a difficult task per se, but once you begin to feel tired, lousy code doesn't look that bad anymore. I took a short nap to rejuvenate my strength, but before doing so also asked a question on this new website popping up in the results all the time, named StackOverflow. Upon waking up I found a few answers, but most importantly they worked. It almost felt like cheating.

    Since then I answered other people questions on SO every now and then. Reward points are being granted by doing so which feel quite nice. What didn't felt so nice was that answers to difficult questions were more unlikely to be voted up, probably because few had the knowledge to understand them, while easier common day issues would get way more attention. Suffice to say that the very system that made it so great was also its greatest fault. As post quality dropped, so did my interest.

    Granted, I found many gems there, but it's time to walk away and wait for the "next thing".
  • March 2, 2011 11:14 PM

    Texts over multiple lines with RMagick

    By Daniel - No Comments
    I recently worked on a project that generated some custom images using RMagick. There were several texts involved with some spanning over multiple rows. While RMagick does provide a caption method that wraps the text, I found it rather limiting. So instead I used the more powerful annotate method which allowed me to set my own font and text position.

    Having just a canvas (an RMagick image for background), I started by creating a new drawing object:

    drawing = Magick::Draw.new

    I then used a method for splitting the text into rows (stolen from a rails helper):

    def word_wrap(text, columns = 80)
      text.split("\n").collect do |line|
        line.length > columns ? line.gsub(/(.{1,#{columns}})(\s+|$)/, "\\1\n").strip : line
      end * "\n"
    end

    Writing the actual text was easier than I initially thought.

    position = 80
    word_wrap(my_long_text, 90).split(\n).each do |row|
      drawing.annotate(canvas, 0, 0, 200, position += 20, row)
    end

    The text is being added at the 200, 100 coordinates, with a line height of 20. That's it.
  • February 27, 2011 1:39 AM

    Website screenshots under linux are about to get easier

    By Daniel - No Comments
    I just published the code that handles the screenshots of mywebsit.es.

    Either use "gem install website_screenshot" or head over to github to get it. I also posted a web service demo to make implementation more straightforward.

    Dependencies include ruby 1.8.6 or higher, ruby qt and curl.
    Tested on Ubuntu LTS and Fedora.
  • January 23, 2011 7:27 PM

    A ruby on rails frontend implementation story

    By Daniel - No Comments
    For the last year I have been working on a large social network website.
    As I preper to move forward I can't help thinking of the challenges that aroused during this time.
    One in particular stood out. The form fields were heavily customised - every field, be it a simple text or select, even file uploads were all styled.
    The design was less than ideal for a project this size to say the least.

    While I didn't code the html I had to find a solution to integrate it that worked well and wouldn't prove to be time consuming.
    The solution I chose was to extend the default form and use it across the site. Even if these forms were to be styled with javascript it would had just resulted in a poor user experience as each page form would briefly be displayed naked then quickly styled.

    Bear in mind that this code runs under Rails 2. It may require some adjustments to work with 3.

    Firstly I defined my own form builder:

    class CustomFormBuilder < ActionView::Helpers::FormBuilder

      include ActionView::Helpers::TagHelper
      include ActionView::Helpers::AssetTagHelper

      ..

    end

    As it was going to be used sitewise I also made it default in my environment file:

    ActionView::Base.default_form_builder = CustomFormBuilder

    Each text field had to be enclosed in a specific span tag with the class "input_text". Targeting with input[type="text"] would had probably worked just as well if you ignore IE6.

    def text_field(method, wrapper_options = {}, input_options = {})
      wrapper_options[:class] = (wrapper_options[:class].to_s + ' input_text').strip
      wrapper_options.reverse_merge!({ :class => 'input_text' })
      content_tag :span, @template.send(:text_field, @object_name, method, objectify_options(input_options)), wrapper_options
    end

    You can style both the wrapper and the input field with separate option hashes.
    The password, textarea and select fields were similarly styled. The latter was albeit more difficult but I'm not going to post the code as the markup differs significantly from one implementation to another.

    After doing these I received an interesting request of extending the label tag, having many fields that were mandatory and had to be displayed accordingly.

    def label(method, text = nil, options = {})
      if options[:required]
        text = (text || method.to_s.humanize) + ' <span class="highlight">*</span>'
      end
      super
    end

    To do the file uploads (which were surprisingly plentiful) I decided on creating my own helpers, rather than just extending the basic "file". This was mostly because I needed both an actual file upload and a photo upload which had a very different behaviour such a live thumbnails. I used flash (swf upload) because it was the only crossbrowser way of selecting multiple files and styling the actual button.

    def flash_photo_upload(name = 'files', options = {})
      locals = {
        :f => self,
        :name => name.to_s,
        :queue_limit => options['queue_limit']
      }

      @template.render :partial => 'partials/flash_file_upload', :locals => locals
    end

    There's a large amount of code responsible for the entire upload process, that's why I isolated it in a partial. Why so much code you ask, well for instance once one or more photos gets uploaded they're displayed in a carousel; also take into consideration that it had to work seamlessly when editing.

    The final piece was styling the submit buttons (and also some links that needed to look as buttons) - rounded cornered of different size and backgrounds using a beautiful but proprietary font with a text shadow. We had to support IE, so CSS3 was out of the question because we needed the rounded corners which don't degrade very well. Legal font issues aside, normally I would be doing this with the sliding doors css technique. I went the extra mile and generated the images in ruby using the same css technique but with rmagick. The code partially supported some css parameters to make styling easier.
    I extracted that code and made it public as a gem named magic_door. The helpers are packed separately as a plugin.

    I hope this helps anyone who faces a similar situation.
  • September 7, 2010 9:30 PM

    Scale and center crop with ImageMagick one liner

    By Daniel - No Comments
    A few days ago I needed an image magick command that scales and crops a picture on its center. I looked up the last project I used it and found the magical line (pun intended). I'll post it here as a future reference for my self and perhaps it will help others as well.

    convert myPhoto.jpg -resize 200x200^ -gravity Center -crop 200x200+0+0 +repage myThumb.png

    The "myPhoto.jpg" picture is being scaled down to 200 pixels - width or height (the one that has lowest size), then it's cropped on the center. "myThumb.png" is the name of the photo that's being created. 
  • Monthly Archives

    • May 2012 (1)
    • October 2011 (1)
    • September 2011 (2)
    • March 2011 (3)
    • February 2011 (1)
    • January 2011 (1)
    • September 2010 (1)
    • August 2010 (1)
    • June 2010 (1)
    • April 2010 (1)
    • December 2009 (1)
    • October 2009 (1)
    • September 2009 (1)
    • August 2009 (1)
    • July 2009 (2)
    • April 2009 (2)
    • February 2009 (1)
    • January 2009 (2)
    • December 2008 (1)
    • October 2008 (1)
  • Pages

    • About / Contact

2008, © Daniel Mircea