Topic: Is there a more efficient way to work dropdowns from other tables.

Hi, all.

Just wondering if there is a better dry way to do this:

I have an inventory program, that I'm writing to learn rails. It has multiple tables, one of the main ones is called parts. Parts has name, manufacturer, vendor, etc columns.
Manufacturer and vendor  columns are just storing ids of records from tables Manufacturers and Vendors. So when I'm creating a form in the view  for "new" action with the dropdowns I need to first get data from those two table in my controller then iterate in my view to show all the options in the dropdown. This is all fine. My question is - when I save the form it complains that I have no @vendors and @manufacturers in my create method. So I have to do @vendors = Vendor.find(:all) again.

It's not a big performance hit, since I only might have potentially 50 records in each table, but it seems to me I should be able to do @vendors = Vendor.find(:all) once in my controller and then use that in many actions.

Please advise. Below are snippets from my code (please excuse crudity):

Controller

  def new
    @vendors = Vendor.find(:all)
    @manufacturers = Manufacturer.find(:all)
    @departments = Department.find(:all)
    part_status_type = StatusType.find_by_name("part status").id
    @part_statuses = Status.find_all_by_status_type(part_status_type)
    @part = Part.new
  end

  def edit
  end
 
  def create
      @vendors = Vendor.find(:all)
    @manufacturers = Manufacturer.find(:all)
    @departments = Department.find(:all)
    part_status_type = StatusType.find_by_name("part status").id
    @part_statuses =Status.find_all_by_status_type(part_status_type)
    @part = Part.new(params[:part])
    if @part.save
        flash[:notice] = 'Part with  id <strong>#' + @part.id.to_s + '</strong> added successfully'
        redirect_to parts_path
    else
        render    :action => 'new'
    end
  end


View
<tr bgcolor="#cccccc">
    <td>Vendor</td>
    <td>Vendor part #</td>   
</tr>
<tr bgcolor="#ffffff">
   
    <td>
        <%= collection_select("part", "vendor", @vendors, "id", "name") %>
    </td>   
    <td><%= f.text_field :vendor_specific_id %></td>   
</tr>
<tr bgcolor="#cccccc">
    <td>Manufacturer</td>
    <td>Manufacturer part #</td>
</tr>
<tr bgcolor="#ffffff">
    <td>
        <%= collection_select("part", "manufacturer", @manufacturers, "id", "name") %>
    </td>   
    <td><%= f.text_field :manufacturer_specific_id %></td>   
</tr>

Re: Is there a more efficient way to work dropdowns from other tables.

konung wrote:

I have an inventory program, that I'm writing to learn rails. It has multiple tables, one of the main ones is called parts. Parts has name, manufacturer, vendor, etc columns.
Manufacturer and vendor  columns are just storing ids of records from tables Manufacturers and Vendors.

Without getting into this too deeply, i can tell you that the foreign key fields would by convention be called "manufacturer_id" and "vendor_id".  That's not your problem though, i think.

One of the rails conventions is that we don't pass large amounts of data between client and server (for obvious reasons).  A consequence of this is that each controller action has to reload the objects it needs.  The question, then, is why do you need to load all of them?  In your create action you're making a new part, right?  It only has one manufacturer_id and one vendor_id, so at most you would only need to load one manufacturer and one vendor, in order to get their ids, and you might not even need to do that:  if you already know the manufacturer and or vendor when you go to the 'new' page, you can pass their ids through to the create controller.

###########################################
#If i've helped you then please recommend me at Working With Rails:
#http://www.workingwithrails.com/person/ … i-williams

Re: Is there a more efficient way to work dropdowns from other tables.

konung wrote:

It's not a big performance hit, since I only might have potentially 50 records in each table, but it seems to me I should be able to do @vendors = Vendor.find(:all) once in my controller and then use that in many actions.

That's only possible using caching, and would be overkill. cache when you see that you have to, no before.

Besides that, i do such stuff always in the form itself:

<%= collection_select("part", "manufacturer", Manufacturers.find(:all), "id", "name") %>
##
#

setting up those variables in the controller seems odd to me, and if i do it like above, i have it out of my way for all views using this form. select lists are only visual representation (you could technically also use a text field and have the user type in the id) so my feeling is this should be the job of the view anyways, not the job of the controller.

Re: Is there a more efficient way to work dropdowns from other tables.

I'll offer a cheesy easy solution.  I won't say if it is good or not.  I'll leave that up to you.

Create a class variable in the controller.  Then use it instead of repopulating the dropdown:

@@zomg_dropdown = SomeTable.find(:all)

def zoot
   ...
   @dropdown_data = @@zomg_dropdown
   ...
end

def reload
   @@zomg_dropdown = SomeTable.find(:all)
end


This didn't work for me in dev, however - I think Rails reloads the classes each time nuking the class variable.

Last edited by tonyennis (2008-10-13 16:20:05)

But if you want it / Then you must find it
But when you have it / There'll be no need for it