I’ve been working on a few new projects lately and wanted to share a few little tips I’ve started doing.
Conditional Buttons for Shared Forms
Something that I like to do is use a shared form for both my edit and new views. Doing this however means I need to be friendly to the user interface and make sure the submit button is properly instructional. So for example if I have a Customer model with an instance variable @customer my button would look like this:
<%= f.submit((@customer.new_record? ? "Create" : "Update") + " Customer") %>
With this I’m checking to see if the @customer instance variable belongs to a new record and if so it’s outputs Create, otherwise it’s an Update button.
Cleaner RedCloth Helper
There is the built-in textile helper that comes with Rails, it’s carage return rendering is a bit lame so most people typically upgrade their RedCloth gem and using something like:
<%= RedCloth.new("My copy that requires formatting").to_html =>
I prefer to instead create an application level helper for redcloth (some people might instead overwrite the textile helper here, but I find that can be confusing to some people looking at your code for the first time). My helper looks like this:
def redcloth(str) RedCloth.new(str).to_html end
So now when I want to redcloth something I just call:
<%= redcloth("My copy that requires formatting") %>
Simple Little Permalink
When I have a simple object that I want to create more user-friendly URLs for, I’ll create a basic permalink. In the instance of the same Customer model from tip 1 above, I like to use the customer name as the permalink. To do this of course the name has to be unique so make sure you are validating it’s uniquiness above all. Then I create a permalink column in the database table and write something like this in my model.
def name=(value) write_attribute :name, value write_attribute :permalink, value.gsub(/\s/, "-").gsub(/[^\w-]/, '').downcase end def to_param permalink end
This uses the value of the name that is entered, clears it of puncuation, replaces spaces with hyphens and drops the casing. The first line makes sure it still remembers it needs to write the value itself to the name column in the model.
Now it’s still important that you confirm that the permalink is unique too, but I’ll let you do that on your own.
So that’s it – I hope you guys find it useful.
write_attribute: never knew this existed and it makes perfect sense. So helpful when you want to overload a setter method with some data normalization or secondary ops. Thanks for pointing it out!
Good tips. I’d like suggest a few small improvements.
Your conditional button code could be extracted into a reusable helper:
def submit_title(object, type=object.class.name.titleize)
(object.new_record? ? “Create ” : “Update “) + type
end
# Create Customer / Update Customer
# Create Client / Update Client
For your RedCloth helper, I recommend naming your helper something more generic, like “markup”. That way you can swap in a different markup parser if you want to without having references to the old one all over your code. I think this is a good idea even if you use the textililze (or markdown) helpers.
For permalinks, have you seen the permalink_fu plugin? There are a couple other plugins out there as well.
The submit button is a perfect place for a small helper that encapsulates the condition: much cleaner, and as you note, a simple-but-useful usability enhancement.
Jeremy, nice submit_title helper – I like that.
I also think you have a good idea on creating a more generic markup helper, but for me I’m pretty well comfortable with RedCloth.
I have indeed played with both permalink_fu and acts_as_slugable, but sometimes I just need a simply solution for a single model and I’d rather not bring their full functionality in to achieve it.
Thanks for the great points.
Screw RedCloth… Textile is not as beautiful as Markdown. We use Markdown for our multipart email notifications coming out of our Rails apps. If they want plain text, Markdown looks AMAZING in that… if they want HTML, well Markdown also has you covered.
RDiscount is screaming fast as well.