views:

66

answers:

1

Hi,

I'm not sure if I'm missing a known design pattern, but I keep coming up against the following problem with RESTful routes Rails.

In my example, I have a users controller that can respond in javascript (:js) format. The default response populates a page element with a list of the paginated users:

# /app/controllers/users_controller.rb
class UsersController < ActionController
  def index
    @users = User.paginate(:all, :page => params[:page], :conditions => ['name ILIKE ?', params[:name])

    respond_to do |format|
      format.html
      format.js
    end
  end
end

The corresponding RJS template would look like:

# /app/views/users/index.js.rjs
page.replace_html :users, :partial => 'users'

This works fine, allowing me to perform AJAX lookups on users. However, in another part of my site (say the user editing form) I would like to perform an AJAX lookup of users, but update a set of ''select'' options or perform an inline autocomplete, rather than update the #users page element, e.g.

# /app/views/users/edit.html.erb
<%= f.text_field :name %>
$('#user_name').autocomplete({url: '/users', data: 'name=value', ...})

My question is what would be the best DRY way to achieve this? I don't think I should need to create a new controller action to correspond to the different view, as this would involve repeating the finder code. The only solution I've come across so far is to build some javascript conditions into my RJS helper:

# /app/views/users/index.js.rjs
page << "if($('#users').length > 0)"
  page.replace_html :users, :partial => 'users'
page << "else"
  page.replace_html :user_options, :partial => 'user_options_for_select'

This feels very brittle, and unclean for Rails. Am I missing something in how I can respond with different views depending on the calling controller?

Appreciate any help! Chris

A: 

In one of them you have a list of users and the other one a list of options.
So even though for now, your two pages are having the same feature, they're independent from each other and you might want to change things for only one of them in the future.

So I'd keep them distinct with two different javascript actions . It'll will allow you to much more easily make them evoluate on their different path.

Anyway as you can see, they're already quite different. You have two different partials and two different html tags id.
Trying to have the same code for them both here seems quite confusing to me.

So yes I'd create two actions, one for the users list and one for their options.

Damien MATHIEU
Thanks for your answer. I'm not sure if the example is clear, but in both cases I'd just be returning a list of user names. In the first example, this would populate the paginated list; in the second, it would populate the <select> list. It could also be the case that I populate another list of users, but in a different layout from example #1. In each case the data is identical, it's just the view I need to change.
Chris
Views are meant to display things differently. If you have twice the same datas but want to display it twice differently, the good way of doing things isn't to do a condition. But to do two views.
Damien MATHIEU
What about moving the condition into the view; would this be a good practice? I'm thinking something along the lines of rendering a different view from within the same action depending on the condition, e.g:render (condition ? view_one : view_two)
Chris