Showing widget/profile_completeness/_next.html.erb where line #52 raised:
compile error
/[path_removed]/_next.html.erb:-3: syntax error, unexpected '=', expecting kEND
next = local_assigns[:next]
^
After debugging into action_view, I realized it was because I foolishly named a partial "_next.html.erb". "next" is apparently some pseudo-reserved word in action_view and if you use it, your template crashes in weird and interesting ways. I particularly like the negative line number in the error message which results from rails pre-pending code to the erb block when compiling the method used for rendering.
Bug filed here.
Update: Apparently, you'll run into this if you name your partial any reserved word in ruby (case, class, etc...)
Monday, September 29, 2008
Actionview error when naming partials " _next.html.erb"
So, today I got this wonderfully cryptic error from the erb compiler:
Tuesday, September 23, 2008
Rails hack: Adding html comments to label partials
Ever want to figure out which partial a block of html is coming from without greping through your entire rails project? Render_partial_comments is a rails plugin that renders html comments to mark the begin and end of partial output. Give it a try:
ruby script/plugin install git://github.com/avvo/render_partial_comments.gitThen enable it by adding this global in config/environments/development.rb (or wherever)
$render_partial_comments = trueThen restart your server... Your rendered html will now include html comments wrapping the output from partials. Should look something like this:
<!-- render_begin 'user/view' --> .... <!-- render_end 'user/view' -->Update: This may have some adverse effects on autocomplete if you use it
Friday, September 19, 2008
belongs_to :dependent => :destroy with foreign key constraints
Moved here
I discovered what I believe to be a bug in activerecord (2.1.0) today. If you have something like the following:
class Person < ActiveRecord::Base
belongs_to :person_address, :dependent => :destroy
end
class PersonAddress < ActiveRecord::Base
has_one :person
end
...and you have for foreign key constraint on person_address_id on the person table to id on the person_address table (which would be a reasonable thing to do) you will get a foreign key constraint error when you try to destroy a person record (if the associated person_address record exists).
I submitted a patch to rails for this, but in the meantime, I found this as a work around:
class Person < ActiveRecord::Base
belongs_to :person_address # note: no :dependent => :destroy
def destroy
super() # first destroy ourselves before we destroy the association
PersonAddress.destroy(self.person_address_id) if self.person_address_id
end
end
Friday, September 12, 2008
Private Mixins - Including helpers in controllers
Despite being fully aware that controllers should include minimal logic, we still have some code that needs to be shared by multiple controllers (and even some views). The easiest way to share code in ruby is, of course, the mixin module. The trouble in rails is that any public methods on controllers are exposed as actions, even ones that come in via mixin. That's trouble.
One solution was to define all methods in our helpers as private. Didn't really work in every scenario and kind of limits testing. What we really wanted was to be able to include modules privately. As far as I can tell, ruby doesn't support this off the shelf, so we decided we give it a shot to see where it took us.
class Module
[:private, :protected].each do |type|
eval %{
def include_#{type}(*prms)
prms.each do |mod|
include(mod)
mod.instance_methods.each do |meth|
#{type}(meth)
end
end
end
}
end
end
This creates two methods include_private and include_protected. These guys wrap the normal include method but then take all the instance methods for the included module and privatize or protected-ize them, respectively.
Then we added this to ApplicationController:
class ApplicationController < ActionController::Base
class << self
alias_method :include_helper, :include_private
end
end
Now we can include helpers in our controllers privately:
class MyController < ApplicationController
include_helper MyHelper
end
Now, it seems to me that there must be a better way of doing this and we would love to see it because our googling came up empty and it seems odd that we had to resort to this, though it seems to fit our needs just fine.
Monday, September 8, 2008
DelSolr - Solr Facets Made Easy in Ruby
delsolr - lightweight solr wrapper for ruby
Here's an example of solr faceting made simple via delsolr:
c = DelSolr::Client.new(:server => 'solr1', :port => 8983)
# faceting by field...
rsp = c.query('dismax', :query => 'mp3 player',
:facets => [{:field => 'brand', :limit => 5, :mincount => 1}]
# now let's output the facet values and counts
rsp.facet_field_values('brand').each do |brand|
puts "#{brand} - #{rsp.facet_field_count('brand', brand)}"
end
# faceting by query... with filtering...
rsp = c.query('dismax', :query => 'mp3 player',
:filters => {:onsale => true},
:facets => [{:query => "instock:true", :name => 'instock'},
{:query => {:price => (0..50), :description => 'cool'}, :name => 'cool_and_cheap'}])
# now let's output some query facets
puts "Instock: #{rsp.facet_query_count_by_name('instock')}"
puts "Sweet: #{rsp.facet_query_count_by_name('cool_and_cheap')}"
We've been using this code internally for a bit, so we'd figure we'd open it up as a gem to see if other people find it useful. There are a number of other gems/plugins that do something similar, but we weren't satisfied with the balance of power and simplicity in any of them, particularly when it comes to faceting. The full documentation is available on the delsolr page
Wednesday, September 3, 2008
Method of the Day: Array#in_groups_of
This one is great for building rows of tables.
<table>
<% @models.in_groups_of(3).each do |row| %>
<tr>
<% row.each do |model| %>
<td><%= model.to_s %></td>
<% end %>
</tr>
<% end %>
</table>
This will render the array in a left-to-right, top-down order. If you want to render in top-down, left-to-right order, try this:
<% num_cols = 3 %>
<% @models.in_groups_of((@models.length/num_cols).ceil).transpose.each do |row| %>
...
That should give you the (more common) column-first layout.
Method of the Day: Array#to_sentence
An Oldy but a goody...
<% a = ['hot dogs', 'hamburgers', 'pizza'] %>
I like <%= a.to_sentence(:connector => 'and') %>.
renders...
I like hot dogs, hamburgers, and pizza.
Subscribe to:
Posts (Atom)