In a recent project, I wanted a link that modifies a row in the database. The provided mockup wanted a link. “To follow the rules of RESTful architecture, anything modifying the database, should not be a GET request” I thought to myself. I realised that Rails provides me with both a link_to and a button_to helper but no hybrid that would be unobtrusive, so I knew I had to make one.
The snippet adds a link after the form, hides the form and make the link submit the form. I have made it non-conflicting to those who use other libraries and jQuery.
To install:
- Use jRails or have the jQuery library included (Prototype not needed)
- Add the snippet to your application.js
- Create your button_to’s with the class
:class => "form_to_link"
Thanks to Kyle Neath and Rein Henrichs with this.
I have worked on many applications that require breadcrumbs. Every time, one of the developers has built a quick custom solution. Finally, I decided that we needed a complete solution that we could easily add to future projects, and thus Crummy was born.
Requirements
I set a few requirements that must be fulfilled in order for me to call the plugin a success. They were:
- Ability to add breadcrumbs at Controller class level (like a before filter)
- Ability to add breadcrumbs in the controller methods (such as actions)
- Ability to add breadcrumbs from the views
- Ability to add breadcrumbs with or without an url
- No variable conflicts (such as instance variables)
- Full and strong spec coverage
- Good documentation
I managed to fulfill these requirements and add a few shiny methods to make life easy.
Examples of Usage
class ApplicationController < ActionController::Baseee
add_crumb 'Home', '/' # This will display on EVERY list of breadcrumbs
end
class BusinessController < ApplicationController
# The load order DOES matter.
add_crumb("Businesses") { |instance| instance.send :businesses_path } # Show on all actions
add_crumb("Comments", :only => [:comments, :show]) { |instance| instance.send :business_comments_path } # Only add the comments link on the comments and show actions.
before_filter :load_comment, :only => “show”
def show
add_crumb @business.display_name, @business
end
def load_comment
@comment = Comment.find(params[:id])
end
end
Golden Feature
One of the most useful argument usage is add_crumb :comment. What this does is turns the symbol into an instance variable (@comment.) Then it roughly translates into:
# add_crumb :comment
before_filter :add_comment_breadcrumb
def add_comment_breadcrumb
add_crumb @comment.to_s, @comment
end
Installation
script/plugin install git://github.com/zachinglis/crummy.git
My final web host?
As with most people who work in the web industry I have an itching sensation to build tons of web applications from the many good ideas I have. My programming weapons of choice, Ruby on Rails and Merb are both a nightmare to deploy. Books even had to be written. Many people will simply not touch the beautiful language of Ruby for this reason alone.
Jamis built Capistrano in promise of easier deployent. The scope of the project was huge and due to it’s complexity and it being open-source, it was very hard to get working. The idea was right and in all theory it should have worked fine. But many people had troubles in one way or another. I was one of those people.
Originally I had a nice Slicehost server but proving to learn how to properly and securely set up a server got the better of me and I decided that it was best to get more of a provided solution. Of course, I wanted to go with Engine Yard but starting at $250 was a bit rich for my blood and I wasn’t sure how worth it, it was.
Not only does Capistrano work out of the box on RailsMachine, but they also have provided a gem to configure the deploy.rb configuration file and for extra tasks. It is incredibly easy to set up an application, or to make changes to one with Capistrano and RailsMachine.
RailsMachine have shown to be amazing hosts. The server setup was a little bit late outside of the given 24 hour setup period. I sent in an email at 24 hours past and at 25 hours past my server was set up and I was billed. The support is efficient, speedy and polite. I have asked quite a bit outside the official scope of support and they helped me along the way.
The plans that they offer are more recommendations, due to the fact that you can customise them very specifically (with price add-ons for better hardware/features) and I have heard that upgrading hardware takes less than an hour. Because of this, if your app is choking but you know that it doesn’t need a huge hardware update; you can slightly modify your server(s) without having to pay an arm and a leg for a system that you obviously do not need.
It would be nice to see a web panel but they hint that one is in the works (on their blog), so I will be watching out for that.
In one of my projects, I mix together two ActiveRecord objects for listing. There is two ways that I could have done this. A seperate model that enfolds my models or merging them with a concat. I did it this way as it only happened once so no need to create yet-another file.
After reading this post, I got a better idea of what to do. That code was OK but I refactored it into better, cleaner and more understandable code.
def list
foo = Foo.find :all
bar = Bar.find :all
foo_bar = foo.concat bar # merge the two arrays
foo_bar = foo_bar.sort_by { |foos_and_bars| foos_and_bars.created_at } # reorganize by created_at date
end
I then created a private method for pagination. I’ve stuck this in my local controller but the application-wide controller may be a better idea if you use it in different controllers.
Anyway, here be the code:
def paginate_array(array, per_page_param=25, page_number_param=0)
per_page_number = per_page_param.to_i == 0 ? 25 : per_page_param.to_i
page_number = page_number_param.nil? 0 : page_number_param.to_i
page_number = per_page_number * page_number
array_count = 0
array.collect { array_count += 1 } # Array does not have the count method so this works nicely.
WillPaginate::Collection.new(page_number, per_page_number, array_count).concat_array
end