One shouldn’t be addicted to too many things at the same time.
1. move your static content of your rails application elsewhere:
config.action_controller.asset_host = "http://assets.example.com"
You can go one step ahead and dump all the crap on Amazon and have RESTful sleeps.
S3 Amazon rails
2. How do your word wrap a large string?
Here are two versions doing that:
b = "";i=1;a.split(/\s+/).collect do |word|
b << "\n" if ( i%7 == 0); b << word +" "; (i += 1);
end
Another version is:
b = a.gsub(/((\S+\s+){8})/,"\\1\b")
3. Custom form builder by Chad Fowler, left my head spinning for a while.
<% form_for :contact, :builder => TabularFormBuilder do |f| %>
<%= f.text_field :name %>
<%= f.text_field :email %>
<%= f.text_field :phone %>
<% end %>
And put this in your application_helper.rb file:
class TabularFormBuilder < ActionView::Helpers::FormBuilder
(field_helpers - %w(check_box radio_button hidden_field)).each do |selector|
src = <<-END_SRC
def #{selector}(field, options = {})
@template.content_tag("tr" ,
@template.content_tag("td" , field.to_s.humanize + ":" ) +
@template.content_tag("td" , super))
end
END_SRC
class_eval src, __FILE__, __LINE__
end
end
What he doesn't explain is, how it works. Well there is this class
FormBuilder, that actually generates the HTML tags when used with form_for
syntax. The best part is, we can define your own form builders.
Now this feature is undocumented so, DHH won't be too happy about it.
And of course, your designer's girl friend will hate your more for this.
So let's get started on this. field_helpers variable holds the HTML
form helpers provided by rails, you will have to dig into the code
of ActionPack a little to see that. Now, Chad doesn't think
check_box , radio_button and hidden fields should go into table rows
and hence avoids beautifying the generated HTML tags for that.
%w(check_box radio_button hidden_field) = ["check_box","radio_button","hidden_field"]
once this nuisance out of our way... next couple of lines
prepare a string for evaluation, which would generate those helper methods.
@template is the current_template, and we are adding tags along with content to it.
Next super important line is:
@template.content_tag("td" , super))
which actually generates td tag and calls super which in effect calls
the original method that you are overriding here.
So after removing meta_programming crap: you can see the method as:
def text_field(field,options = {})
@template.content_tag("tr",
@template.content_tag("tr",...
@template.content_tag("td",super))
...
Next comes class_eval, which basically executes the code string in the
context of current class, which is TabularFormBuilder
Okay, next comes ability to utilizes model generated error messages in your form:
You will have to slightly change your Form builder code for that:
@template.content_tag("td", super + options[:append].to_s + error_message_on(@object, field, options[:label] || field.to_s.humanize)))
Another gem of a method is this:
def tabular_form_for(name, object = nil, options = nil, &proc)
concat("<table>" , proc.binding)
form_for(name,
object,
(options||{}).merge(:builder => TabularFormBuilder),
&proc)
concat("</table>" , proc.binding)
end
It uses several of undocumented methods. calling
makes sure that, context witin which the block was defined is preserved.
so calling:
concat("<table>",proc.binding)
would generate:
Then question arises, then why waste time and energy with
proc.binding
,
why not just do <%= "<table>" %>
.
The reason is, concat is the only
way to output text within a block.
If you see source code of concat method if would become a little more clear:
def concat(string, binding)
eval(ActionView::Base.erb_variable, binding) << string
end
so normally form_for which accepts a block/proc, we convert the block to
proc and pass it to form_for for execution.
So finally the view would like this:
<html>
<head>
<%= stylesheet_link_tag "application" %>
</head>
<body>
<% tabular_form_for :contact do |f| %>
<%= f.text_field :name %>
<%= f.text_field :email %>
<%= f.text_field :phone %>
<% end %>
</body>
</html>