Forum: Ruby on Rails using a variable to invoke a custom method within autocomple

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
777892eb38d2e6a4eb915d558068c971?d=identicon&s=25 Dimmerswitch (Guest)
on 2007-02-16 02:22
(Received via mailing list)
I'm implementing a version of the autocompletion script found at
http://ricardo.pacheco.name/blog/articles/2006/07/26/using-
autocomplete-with-belongs_to-fields and have run into a stumbling
block.

The issue involves passing in a variable to indicate which custom
method should be invoked. I have an ugly workaround (a duplicate
function hardcoded to use the custom method), but would like to learn
a better way to handle this case. It feels like I'm missing something
simple, but I'll be damned if I can see it.

# from: app/helpers/application_helper.rb

def indexed_auto_complete_result(entries, entityType, field, index)
  return unless entries
  items = entries.map { |entry| content_tag("li", entry[field], "id"
=> entityType+'::'+entry[index].to_s) }
  content_tag("ul", items.uniq)
end

This works fine for referencing model attributes which exist in the
"Highlights" table (name, description, etc.) but fails if 'field' is
passed in as "name_with_place". The unordered list is created, but
it's full of empty <li> tags. If I change it to use entry.field I get
NoMethodError (undefined method 'field') errors in the log.

My eventual workaround was to add this function for those times I need
to access the name_with_place method. This works as desired, and
properly invokes the custom name_with_place method. It's clearly not
DRY, though.

  def indexed_auto_complete_result_with_place(entries, entityType,
field, index)
    return unless entries
    items = entries.map { |entry| content_tag("li",
entry.name_with_place, "id" => entityType+'::'+entry[index].to_s)}
    content_tag("ul", items.uniq)
  end



# from: app/models/highlight.rb
belongs_to :place

def name_with_place
  if self.place.nil?
    self.name
  else
   "#{self.name} (#{self.place.name})"
 end
end

# from: app/controllers/highlights_controller.rb
def auto_complete_for_highlight_internal_name
  find_options = {
    :conditions => [ "LOWER(name) LIKE ?", '%' +params[:highlight]
[:internal_name].downcase + '%' ],
    :order  => "name ASC",
    :limit  => 10
  }
  @highlights = Highlight.find(:all,find_options)
  render :inline => "<%= indexed_auto_complete_result @highlights,
'highlight_id', 'name_with_place', 'id' %>"
end

# from: public/javascripts/application.js

function auto_complete_on_select(element, selectedElement)
{
  var entityParts = selectedElement.id.split('::');
  var entityType = entityParts[0];
  var entityId   = entityParts[1];
  document.getElementById(entityType).value = entityId;
}

# from: app/views/highlights/index.rhtml

<% form_tag('/highlights/edit', :method => :post) do %>
<%= text_field_with_auto_complete :highlight, :internal_name, { :size
=> 40 }, { :after_update_element =>
'auto_complete_and_redirect_on_select' } %>
<%= hidden_field 'highlight', 'id' %>
<%= submit_tag("Edit") %>
<% end -%>
71c90d30f8c437a593aeb5588408ec1a?d=identicon&s=25 Jon (Guest)
on 2007-02-16 02:48
Not sure if this is what you want, but object.send(function_name) will
do the trick for cases like that.  Just be careful since I think .send
will execute any function, public or private.
777892eb38d2e6a4eb915d558068c971?d=identicon&s=25 Dimmerswitch (Guest)
on 2007-02-16 14:57
(Received via mailing list)
That works great for the dropdown. I'll take a look at .send and the
potential for executing any object method, which might make this
approach a nonstarter.

Thanks, Jon
This topic is locked and can not be replied to.