q: how to list one model in a different model's view form

3 views
Skip to first unread message

Adam Teale

unread,
Jul 3, 2008, 2:56:30 AM7/3/08
to rubyonra...@googlegroups.com
Hi Guys,

i have a the following models:

job
has_many :job_divisions
has_many :divisions

division
belongs_to :job
has_many :job_divisions

job_division
belongs_to :job
belongs_to :division

When I do a Job.new I would like to have a list of all the divisions,
and be able to select them with checkboxes.
Once the Job.create is run a job_division.create is run for each of the
selected divisions in the above list.
Something like that.

I can't work out how to get the list of Divisions to appear in the View
for the Job.new, and then how to get it to save all the info.

Any ideas? Any pointers would be great

Cheers

Adam
--
Posted via http://www.ruby-forum.com/.

"Wolas!"

unread,
Jul 3, 2008, 3:27:39 AM7/3/08
to Ruby on Rails: Talk
job
has_and_belongs_to_many :divisions

division
has_and_belongs_to_many: jobs

divisions_jobs (its a many to many join table, rails conventions make
it alphabetical order and plurars)
has no model but in the table should be
job_id:integer
division_id:integer

then you can do in the view
<%= check_box_tag "job[division_ids][]", division.id,
@job.divisions.include?(division) %>
<%= division.name %>

Remember that in HTML, when checkboxes are not checked, they DONT
appear in params at all (as opposed to appeaaring as :name => false)

here is a source that might help:
http://railscasts.com/episodes/17

its a bit old (rails 1.2) but still aplies

hope this helps

On Jul 3, 7:56 am, Adam Teale <rails-mailing-l...@andreas-s.net>
wrote:

Adam Teale

unread,
Jul 3, 2008, 5:49:17 AM7/3/08
to rubyonra...@googlegroups.com
Wolas thankyou very much!

I got solution over at railforum.com as well:
http://railsforum.com/viewtopic.php?pid=67294#p67294

Thankyou very much!

Adam Teale

unread,
Jul 3, 2008, 2:28:43 PM7/3/08
to rubyonra...@googlegroups.com
I have another question, I would like to use the same setup but this
time with a text_field in the form.

The additional field is for a column in the divisions_jobs called
'shotamount'

[code]
<% @job.divisions.each do |d| %>
<p><%= text_field_tag d.shotamount %> <%= d.name %><br/>
<% end %>
[/code]

The form loads fine, I can type in numbers to the text_fields, and then
hit submit.

However the divisions_jobs.shotamount is not updating in table.

Any ideas?

"Wolas!"

unread,
Jul 3, 2008, 3:28:33 PM7/3/08
to Ruby on Rails: Talk
> <p><%= text_field_tag d.shotamount %> <%= d.name %><br/>

1) You have the shotamount pointing to the divisions table, not the
joined table. (d.shotamount? then the model division has a column
shotamount or a method shotamount?)
2) The text_field_tag gives you a plain text field. the controller
will not use the value at all to do mass assignment (what it does to
update_attributes or Model.new(:foo => 'bar' ).
3) if you look at the api: http://api.rubyonrails.org/classes/ActionView/Helpers/FormTagHelper.html#M001698
you have put the wrong arguments in the wrong places. Ruby will let
you do this (its not like java, and rails will do even more auto-magik
(accept integers as strings and vice versa) ) so always always read
the api of a function if you are unsure.
4) in HABTM you cant have rich associations. ie: no more attributes
than 2 (maybe more) ids and thats it. if you need rich associations,
you ill have to use has_many :through. there are plenty of blogs about
i recommend Josh suser (i think its spelt like this)

hope it helps

On Jul 3, 7:28 pm, Adam Teale <rails-mailing-l...@andreas-s.net>
wrote:

Adam Teale

unread,
Jul 4, 2008, 4:04:35 AM7/4/08
to rubyonra...@googlegroups.com
Hi Wolas thanks for continuing to help me out !

I am now trying to do this with "has_many :through" as you suggested but
have been losing hair trying to work this out. I don't really get it,
and the frustration of not understanding is killing me!

Would you be able to have a look again?
Thanks if you can!
Adam

#JOB MODEL
class Job < ActiveRecord::Base
has_many :job_divisions
has_many :divisions, :through => :job_divisions

def self.options_for_select
self.find(:all).collect{|job| [job.job_title]}
end

def division_ids(divids=[])
divids.each do |divid|
job_divisions.build(:division_id => divid)
end
end
end

#DIVISION MODEL
class Division < ActiveRecord::Base
has_many :job_divisions
has_many :jobs, :through => :job_divisions
end

#JOB_DIVISION MODEL
class JobDivision < ActiveRecord::Base
belongs_to :job
belongs_to :division
end

#JOB VIEW
<h1>New job</h1>

<% form_for(@job) do |f| %>
<p>
<b>Job Title</b><br />
<%= f.text_field :job_title %>
</p>

<b>Division</b><br />

<% Division.find(:all).each do |d| %>
<%= check_box_tag "job[division_ids][]", d.id %> <%= d.name %>
<% end %>

<p>
<%= f.submit "Create" %>
</p>
<% end %>

"Wolas!"

unread,
Jul 4, 2008, 6:03:07 AM7/4/08
to Ruby on Rails: Talk
Ahhh, we have switched methods! the "job[division_ids][]" business
works for HABTM. so:

what you want to do is attach a division to a job via a checkbox, so
the presence of that check box means the division will be added. ok.

<%= check_box_tag "divisions[#{division.name}]", true,
job.divisions.include?(division) %>

this will create a params in the form of:

{"divisions" => {'finance' => true, 'it' => 'true'} }

this is not understood by rails by default. so we have to work a bit
in the controller. (most important thing is to remember that if the
check box is unchecked it wil NOT give 'name' => false. it will just
not appear at all)

def update
job = Job.find(params[:id])

# here is the beauty of ruby...whatever gets returned by the if
# block gets assigned to jobs-new-divisions
jobs_new_divisions = if params[:divisions]
# we only want the name because presence means it was checked
params[:divisions].map{|key, value| key }
else
# just in case we have everything unchecked
[]
end

if job.update_attributes(params[:job])
Job.divisions = jobs_new_divisions
Job.save
flash[:notice] = "Roles for #{player.name} succesfully updated"
redirect_to :action => 'index'
else
# bla bla bla
end
end

hope it helps

On Jul 4, 9:04 am, Adam Teale <rails-mailing-l...@andreas-s.net>
wrote:

"Wolas!"

unread,
Jul 4, 2008, 6:07:43 AM7/4/08
to Ruby on Rails: Talk
even better (refactoring...)

def update
job = Job.find(params[:id])

if job.update_attributes(params[:job])
# here is the beauty of ruby...whatever gets returned by the if
# block gets assigned to jobs-new-divisions
jobs.divisions = if params[:divisions]
# we only want the name because presence means it was checked
params[:divisions].map{|key, value| key }
else
# just in case we have everything unchecked
[]
end

Job.save! #bang because we should be certain that everything is
ok.

flash[:notice] = "#{job.name} succesfully updated"
redirect_to :action => 'index'
else
# bla bla bla
end
end

Adam Teale

unread,
Jul 4, 2008, 7:18:33 AM7/4/08
to rubyonra...@googlegroups.com
Hi Wolas!

Thankyou so much for your efforts to explain all this.

I have used your code but rails seems to not know about the variable
'division'

:) If you have a paypal account I will happily drop some money in it!

I am so brain dead after looking at this all day!

Thanks!

Adam

#################################
NameError in Jobs#new

Showing jobs/new.html.erb where line #16 raised:

undefined local variable or method `division' for
#<ActionView::Base:0x2624f24>
Extracted source (around line #16):

13: <b>Division</b><br />
14:
15: <% Division.find(:all).each do |d| %>
16: <%= check_box_tag "divisions[#{division.name}]", true,
job.divisions.include?(division) %>
17: <% end %>
18:
19: <p>
RAILS_ROOT: /Users/ateale/rails/frameworx

Application Trace | Framework Trace | Full Trace
app/views/jobs/new.html.erb:16:in
`_run_erb_47app47views47jobs47new46html46erb'
app/views/jobs/new.html.erb:15:in `each'
app/views/jobs/new.html.erb:15:in
`_run_erb_47app47views47jobs47new46html46erb'
app/views/jobs/new.html.erb:7:in
`_run_erb_47app47views47jobs47new46html46erb'
app/controllers/jobs_controller.rb:40:in `new'
Request

Parameters:

None
Show session dump

Response

Headers:

{"cookie"=>[],
"Content-Type"=>"text/html",
"Cache-Control"=>"no-cache"}
#################################

martin curtis

unread,
Jul 4, 2008, 7:28:14 AM7/4/08
to rubyonra...@googlegroups.com
hi adam,

i think your problem is that you've declared 'd' as the local variable you're using with the enumeration (when you
say, 'each do |d|'.

try changing |d| to |division| and see if that helps.

hth

phantom


Quoting Adam Teale <rails-mai...@andreas-s.net>:


--


-------------------------------------------------
Visit Pipex Business: The homepage for UK Small Businesses

Go to http://www.pipex.co.uk/business-services

"Wolas!"

unread,
Jul 4, 2008, 8:39:55 AM7/4/08
to Ruby on Rails: Talk
Exactly. sorry, i did a quick copy and paste and forgot about that

For the paypal, please, keep it and invite one of your pals to a beer,
celebrating the weekend.

glad to help

j

On Jul 4, 12:28 pm, martin curtis <mar...@thequokkagroup.com> wrote:
> hi adam,
>
> i think your problem is that you've declared 'd' as the local variable you're using with the enumeration (when you
> say, 'each do |d|'.
>
> try changing |d| to |division| and see if that helps.
>
> hth
>
> phantom
>
> > Posted viahttp://www.ruby-forum.com/.

Adam Teale

unread,
Jul 4, 2008, 9:25:30 PM7/4/08
to rubyonra...@googlegroups.com
Wolas & Martin thanks again!

The Job.New form now runs without error!!! Cool!!

But, the job_division model (join?) table does not get the job's
divisions saved to it.

Any ideas?

Thanks!

Adam

Reply all
Reply to author
Forward
0 new messages