Routing AJAX request from partials to a specific controller

Hey :slight_smile:

I’m creating this backend administration interface for a very large
book database.

I have created, IMHO, a really cool structure of partials that I can
reuse in different situations, and offer nested editing of the backend
data, like in this little “use case”:

  • The admin does a search on books and is presented with a tabular
    list of books with a short description in each row.
    -=-=- The ‘books’ controller fetches the data, index.rhtml passes the
    books array to a partial that renders the list
  • The admin clicks an entry, and an ajax call is made that replaces
    the small descriptive table row with a detailed and editable larger
    presentation of this particular book.
    -=-=- The book has a property, book.series_participations which is
    like a list of “memberships” with different series of books. This
    array attribute is passed directly to a partial, “/
    series_participations/backend_table_list”, which works in basically
    exactly the same way as the books partial does, that is, it lists all
    participations in a nested table which again allows the admin to click
    and edit a participation directly in the interface without refreshing
    or redirecting. The same partial is also used directly when listing,
    searching and editing SeriesParticipation instances, and indirectly
    (vis-a-vis this book example) in the Series editing module.

So, the series_participation partials will be used by any of three
controllers. This is not really any problem until I start using AJAX.
Editing, saving, deleting, what have you works fine as long as I
always use absolute paths for rendering the partials and as long as I
remember to specify the (correct) :controller in the partials.
Otherwise, the partials would try to commit etc. to the current
controller, e.g. in this example, if editing a series participation
opened via the books list, it would try to commit to the :save action
on the books controller, which would obviously fail.

Okay, so the problem arises with auto_complete fields in partials that
don’t “belong” to the current controller. I’ve already moved
auto_complete actions into a dedicated module, so that I can load the
ones I need for any one controller without duplicating my code. For
instance, there’s this one (this is the beginning of my
auto_complete_for.rb file):

module AutoCompleteFor

module UserPrintedName
def auto_complete_for_user_printed_name
search = params[:user][:printed_name]
@users = User.find_by_sql(“SELECT TOP 25 id, first_names,
last_name, email FROM users WHERE (first_names + ’ ’ + last_name
LIKE ‘%#{search.sql_safe}%’) ORDER BY first_names ASC, last_name ASC”)
|| [] unless search.blank?
render :inline => “<%= indexed_auto_complete_result @users,
‘#{self.class.to_s.gsub(/Controller$/,
‘’).underscore.singularize}_user_id’, ‘printed_name’, ‘id’ %>”
end
end

As you can see, I extract the name of the current controller to make
it possible to add it to different controllers, where the receiving
HTML elements will have different names due to the different models
that forms are created for.

This works fine as long as the form that uses a particular
auto_completer “matches” the controller that is responsible for the
form being rendered. That is, if I went into a
group_memberships_controller and included the auto_completer above,
then it would work for the form that directly relates to this type of
model, because it would have a html form element called
group_memebership_user_id, representing group_membership.user_id.

However, consider a Series controller that renders a list of series
that books might participate in. The admin opens a series in this
list, which renders a series_participations partial list to show the
books that participate in the series, but also renders a form to make
it possible to create new series_participations, effectively assigning
more books to the series in question.

This form will use an auto_completer for book titles so the admin can
quickly find the book to include in the series. When the
auto_completer executes, it’ll not ask the series_participations
controller to get the results, it’ll ask the series controller, as
that was the one that rendered the form. But this service really
should be provided by the controller that’ll eventually save the model
as that is the only one who knows exactly how the form is constructed.
Even if I included my auto_completer for this particular case in
series_controller, it would try to deliver the results to the wrong
form elements, as it logically assumes the form elements belong to
series, not series_participations.

Okay, I know I’m rambling here, guess that just underlines my
pickle… Basically, what I want to do, is force these auto_complete
request to a particular controller, but I can’t see how to do that.
observe_field works, as I can specify the :controller in the url. But
text_field_with_auto_complete does not.

Any ideas?

Thanks,
Daniel :slight_smile: