How to populate a table with id of selected item from another table

Hi,

I have a “New Expense” form that includes a select field named vendor
that provides a a drop-down list of all vendors.

When a user makes a selection of a vendor-name, that name populates
the vendor field of the new Expense record. I’m happy with the drop-
down list of names, but I’d rather populate the Expense record with
the ID of the vendor.

IMHO, this is a common database problem. Can you point me to a
simple example on the Web for handling this. I’ve found plenty of
HABTM examples with check-boxes, but none (so far) exactly on point.

Thanks in Advance,
Richard

On Sun, Jun 27, 2010 at 1:28 AM, RichardOnRails
[email protected] wrote:

I have a “New Expense” form that includes a select field named vendor
that provides a a drop-down list of all vendors.

When a user makes a selection of a vendor-name, that name populates
the vendor field of the new Expense record. I’m happy with the drop-
down list of names, but I’d rather populate the Expense record with
the ID of the vendor.

OK, so populate the option values with the ID. This is basic HTML.


Hassan S. ------------------------ [email protected]
twitter: @hassan

RichardOnRails wrote:

Hi,

I have a “New Expense” form that includes a select field named vendor
that provides a a drop-down list of all vendors.

When a user makes a selection of a vendor-name, that name populates
the vendor field of the new Expense record. I’m happy with the drop-
down list of names, but I’d rather populate the Expense record with
the ID of the vendor.

IMHO, this is a common database problem. Can you point me to a
simple example on the Web for handling this. I’ve found plenty of
HABTM examples with check-boxes, but none (so far) exactly on point.

Just use collection_select or something. What exactly are you having
trouble with?

Thanks in Advance,
Richard

Thanks for your responses, Hassan and Marnen.

This is what I had, which returned vendors’ names and parenthesized
nicknames:

<%   def parens(s); s.empty? ? "" : " (#{s})"; end -%>
<% @current_vendors =

Vendor.find(:all, :order=>“nickname”).collect { |v|
v.nickname + parens(v.qbname) } %>
<%= f.select :vendor, @current_vendors %>

In response, to Hassan’s suggestion, I used the following which (as I
expected) presented merely ids and no names which a user could use to
identify the desired vendor:

<% @current_vendors =

Vendor.find(:all, :order=>“nickname”).collect { |v|
v.id } %>
<%= f.select :vendor, @current_vendors %>

What I want is to have vendor-names to be displayed in the drop-down
and the selected name to be displayed in the form but, upon
submission, have the selected vendor’s ID stored in the database
rather than the selected name.

Best wishes,
Richard

On Jun 27, 4:28 am, RichardOnRails

On Sun, Jun 27, 2010 at 8:07 AM, RichardOnRails
[email protected] wrote:

<%= f.select :vendor, @current_vendors %>

In response, to Hassan’s suggestion, I used the following which (as I
expected) presented merely ids and no names which a user could use to
identify the desired vendor:

If you (hint, hint) look at the API doc for select, you’ll see an
example
of exactly the result you’re trying to achieve.


Hassan S. ------------------------ [email protected]
twitter: @hassan

Okay, guys: I can take a hint :slight_smile: Finally I did a Google search based
on your hit that got me what I was heretofore unable to find: “rails
api select”

I don’t have time today to code and test this, so I’ll just post my
ideas here to see if they sound sensible to you guys.

In my “New Expense” form:
<%= f.collection_select(:vendor, :vendor_id, Vendor.all, :id,
name_w_nickname -%>

In my Expense class:
belongs_to :vendor

In my Vendor class:
has_many :expenses
and
def name_w_nickname
%<%s (%s)> % [name, nickname]
end

I need to do something about possible nil in the nickname field,
maybe: nickname ||= “”.

If you guys are up to it, I’d appreciate any observations you may
care to offer.

Best wishes,
Richard

On Jun 27, 4:28 am, RichardOnRails

Hassan S. wrote:

On Sun, Jun 27, 2010 at 8:07 AM, RichardOnRails
[email protected] wrote:

� �<%= f.select :vendor, @current_vendors %>

In response, to Hassan’s suggestion, I used the following which (as I
expected) presented merely ids and no names which a user could use to
identify the desired vendor:

If you (hint, hint) look at the API doc for select, you’ll see an
example
of exactly the result you’re trying to achieve.


Hassan S. ------------------------ [email protected]
twitter: @hassan

Yup. And also, get the DB queries out of the view. They belong in the
controller or model; the view should never ever touch the DB.

On Sun, Jun 27, 2010 at 10:00 AM, RichardOnRails
[email protected] wrote:

Okay, guys: I can take a hint :slight_smile: Finally I did a Google search based
on your hit that got me what I was heretofore unable to find: “rails
api select”

Wow. You’ve been doing Rails development without using the
API docs? Kinda like playing tennis in the dark. in handcuffs. :slight_smile:

In my “New Expense” form:
<%= f.collection_select(:vendor, :vendor_id, Vendor.all, :id,
name_w_nickname -%>

As already mentioned – don’t do DB access in the view. Move that
Vendor.all to your controller and use it to set a var, e.g. @vendors.

Aside from theoretical considerations, it means you don’t have to
change any views when you have a business need to replace the
Vendor.all with, say, a named scope like Vendor.approved.

FWIW,

Hassan S. ------------------------ [email protected]
twitter: @hassan

Hi Hissan,

Thanks for your response.

Wow. You’ve been doing Rails development without using the
API docs? Kinda like playing tennis in the dark. in handcuffs. :slight_smile:

Well, I wasn’t completely without resources, e.g. the links (now
expanded, thanks to you) I maintain under one Firefox tab:
Ruby-Doc.org/core


Ruby Standard Library
Documentation


Ruby/
QuickRef.html


RubyOnRails
Guide: Migrations


rails-scriptserver-command-line-options


RubyOnRails
Guide: command_line


RubyOnRails Migrations CheatSheet


RubyOnRails: FormOptionsHelper

and my Rails library:
The Rails Way
Rails Cookbook
Practical Prototype & Script.aculo.us
Rails Recipes
Advanced Rails Recipes
Practical REST on Rails 2 Projects
… and quite a few more

That was the fun part. Here’s the serious question:

  1. When I bring up my app and click the link for “New Expense”, I see
    http://localhost:3000/expenses/new” in Firefox’ Address bar and I get
    the following 10 lines or so:

NameError in Expenses#new

Showing app/views/expenses/new.html.erb where line #10 raised:

undefined local variable or method `nickname’ for #<ActionView::Base:
0x442c8f0>

Extracted source (around line #10):

7:
8:


9: <%= f.label :vendor %>

10: <%= f.collection_select(:vendor, :vendor_id, @vendors, :id,
nickname) -%>
11: <%= link_to ‘New
Vendor’, :controller=>‘vendors’, :action=>‘new’ %>
12:


13:

  1. I think “nickname” is a legitimate method for Vendor. For example,
    if I load Firefox’ Address bar with “http://localhost:3000/vendors”, I
    get:

Listing vendors
Home Vendor Expense
Nickname QB_name
001v One Show Edit Destroy
002v Two Show Edit Destroy
003nick 003qb Show Edit Destroy
[snip]

  1. I tried a colon in front of “nickname” in the f.collection_select
    statement to no avail; besides, the documentation you referred to
    suggested a bareword.

  2. Any ideas?

Thanks in Advance,
Richard

On Jun 27, 2:14 pm, Hassan S. [email protected]

On Mon, Jun 28, 2010 at 1:06 PM, RichardOnRails
[email protected] wrote:

undefined local variable or method `nickname’ for #<ActionView::Base:
0x442c8f0>

Extracted source (around line #10):

10: <%= f.collection_select(:vendor, :vendor_id, @vendors, :id,
nickname) -%>

  1. I tried a colon in front of “nickname” in the f.collection_select
    statement to no avail; besides, the documentation you referred to
    suggested a bareword.

? I’m looking at (unframed)

http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#M002303
with this ‘sample usage’:

collection_select(:post, :author_id, Author.all, :id,
:name_with_initial, {:prompt => true})

Are you sure you got the exact same error using :nickname ?

If so, what’s the code that creates @vendors ?


Hassan S. ------------------------ [email protected]
twitter: @hassan

Hi Hassan,

Thanks for your continued consideration of my problem. I hope some of
the following is helpful, though it seems like way to much
information.

? I’m looking at (unframed)

http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelp...
with this ‘sample usage’:

collection_select(:post, :author_id, Author.all, :id,
:name_with_initial, {:prompt => true})

Here’s the section of of the doc I looked at:
ActionView::Helpers::FormOptionsHelper,
which seems to match the portion you cited.

Are you sure you got the exact same error using :nickname ?

Since this section referenced a method that returned a string, I took
a short-cut to simply name an object whose value was a string. But in
case that’s the cause of the problem, I changed my app to closely
follow the example in the doc.

If so, what’s the code that creates @vendors ?
Good question: I DON’T KNOW! I see a several methods in app
\controllers\vendors_controller.rb the populate @vendors with
Vendor.all.
Maybe the absence of an assignment to @vendors is what’s wrong, but I
don’t know what to do about it/

Carrying on in case the changes I made are useful, I note that this
section shows the command format as follows:

collection_select(object, method, collection, value_method,
text_method, options = {}, html_options = {})

It shows the object structure to be used with this method:
class Post < ActiveRecord::Base
belongs_to :author
end
class Author < ActiveRecord::Base
has_many :posts
def name_with_initial
“#{first_name.first}. #{last_name}”
end
end

I’ve got: app\models\expense.rb:
class Expense < ActiveRecord::Base
belongs_to :vendor
end

and app\models\vendor.rb:
class Vendor < ActiveRecord::Base
has_many :expenses

  def name
      #{nickname}
end

I’ve got a revised app\views\expenses\new.html.erb, lines 8-12 in
order to follow the example more exactly:

<%= f.label :vendor %>
<%= f.collection_select(:vendor, :vendor_id, @vendors, :id, :name) -%> <%= link_to 'New Vendor', :controller=>'vendors', :action=>'new' %>

When I run the app and click on the New Expense link, I get a
revised symptom, which is the error page below starting with
NoMethodError in Expenses#new in 24-point font.

I can post all the app’s code or any partion thereof in a zip file if
that would be helpful to you.

Thank you for helping me to get this functionality going.

Best wishes,
Richard

NoMethodError in Expenses#new
Showing app/views/expenses/new.html.erb where line #10 raised:
undefined method merge' for :name:Symbol Extracted source (around line #10): 7: 8: <p> 9: <%= f.label :vendor %><br /> 10: <%= f.collection_select(:vendor, :vendor_id, @vendors, :id, :name) -%> 11: <%= link_to 'New Vendor', :controller=>'vendors', :action=>'new' %> 12: </p> 13: <p> RAILS_ROOT: K:/_Projects/Ruby/_Rails_Apps/_EIMS/RTS Application Trace | Framework Trace | Full Trace K:/_Utilities/ruby186-26_rc2/ruby/lib/ruby/gems/1.8/gems/ actionpack-2.3.5/lib/action_view/helpers/form_helper.rb:1025:in objectify_options’
K:/_Utilities/ruby186-26_rc2/ruby/lib/ruby/gems/1.8/gems/
actionpack-2.3.5/lib/action_view/helpers/form_options_helper.rb:588:in
collection_select' K:/_Projects/Ruby/_Rails_Apps/_EIMS/RTS/app/views/expenses/ new.html.erb:10:in _run_erb_app47views47expenses47new46html46erb’
K:/_Projects/Ruby/_Rails_Apps/_EIMS/RTS/app/views/expenses/
new.html.erb:5:in _run_erb_app47views47expenses47new46html46erb' K:/_Projects/Ruby/_Rails_Apps/_EIMS/RTS/app/controllers/ expenses_controller.rb:30:in new’
Request
Parameters:
None
Show session dump
Response
Headers:
{“Content-Type”=>“text/html”,
“Cache-Control”=>“no-cache”}

On Jun 28, 4:42Â pm, Hassan S. [email protected]

Hassan,

Please hold off on looking at my last, unreasonably large post. I’m
embarrassed to have posted such a monstrosity.

I found a bunch of tutorials on collection_select, so I should be
able to discover where I’ve gone astray in trying to apply that method
in my app. I’ll post back how I solved my problem using those
resources, should I be so fortunate.

Best wishes,
Richard

On Jun 28, 4:42 pm, Hassan S. [email protected]