As I stated before, the location is added to the locations table and
the profile is added to the profiles table (if new). The problem is
that the join table is not updated to match the association.
Here is my profiles controller:
# GET /profiles/new
def new
@devices = Device.find(:all)
@profile = Profile.new
@profile.websites.build # creates first website fieldset
@profile.numbers.build # creates first number fieldset
@profile.emails.build # creates first email fieldset
@profile.locations.build # creates first location fieldset
@profile.notes.build # creates first note fieldset
end
# GET /profiles/1/edit
def edit
@profile = Profile.find(params[:id])
end
# POST /profiles
def create
@profile = Profile.new(params[:profile])
if @profile.save
flash[:notice] = "Successfully created profile!"
redirect_to profile_path(@profile)
else
render :action => ''new''
end
end
# PUT /profiles/1
def update
params[:profile][:existing_email_attributes] ||= {}
params[:profile][:existing_website_attributes] ||= {}
params[:profile][:existing_location_attributes] ||= {}
params[:profile][:existing_number_attributes] ||= {}
params[:profile][:existing_note_attributes] ||= {}
@profile = Profile.find(params[:id])
if @profile.update_attributes(params[:profile])
flash[:notice] = "Successfully updated profile!"
redirect_to profile_path(@profile)
else
render :action => ''edit''
end
end
profile.rb
class Profile < ActiveRecord::Base
after_update :save_numbers
after_update :save_emails
after_update :save_locations
after_update :save_websites
after_update :save_notes
belongs_to :user
belongs_to :type
has_many :numbers,
:dependent => :delete_all
has_many :emails,
:dependent => :delete_all
has_many :websites,
:dependent => :delete_all
has_many :notes,
:dependent => :delete_all
has_and_belongs_to_many :locations
# Emails
def new_email_attributes=(email_attributes)
email_attributes.each do |attributes|
emails.build(attributes)
end
end
def existing_email_attributes=(email_attributes)
emails.reject(&:new_record?).each do |email|
attributes = email_attributes[email.id.to_s]
if attributes
email.attributes = attributes
else
emails.delete(email)
end
end
end
def save_emails
emails.each do |email|
email.save(false)
end
end
# Numbers
def new_number_attributes=(number_attributes)
number_attributes.each do |attributes|
numbers.build(attributes)
end
end
def existing_number_attributes=(number_attributes)
numbers.reject(&:new_record?).each do |number|
attributes = number_attributes[number.id.to_s]
if attributes
number.attributes = attributes
else
numbers.delete(number)
end
end
end
def save_numbers
numbers.each do |number|
number.save(false)
end
end
# Websites
def new_website_attributes=(website_attributes)
website_attributes.each do |attributes|
websites.build(attributes)
end
end
def existing_website_attributes=(website_attributes)
websites.reject(&:new_record?).each do |website|
attributes = website_attributes[website.id.to_s]
if attributes
website.attributes = attributes
else
websites.delete(website)
end
end
end
def save_websites
websites.each do |website|
website.save(false)
end
end
# Locations
def new_location_attributes=(location_attributes)
location_attributes.each do |attributes|
locations.build(attributes)
end
end
def existing_location_attributes=(location_attributes)
locations.reject(&:new_record?).each do |location|
attributes = location_attributes[location.id.to_s]
if attributes
location.attributes = attributes
else
locations.delete(location)
end
end
end
def save_locations
locations.each do |location|
location.save(false)
end
end
# Notes
def new_note_attributes=(note_attributes)
note_attributes.each do |attributes|
notes.build(attributes)
end
end
def existing_note_attributes=(note_attributes)
notes.reject(&:new_record?).each do |note|
attributes = note_attributes[note.id.to_s]
if attributes
note.attributes = attributes
else
notes.delete(note)
end
end
end
def save_notes
notes.each do |note|
note.save(false)
end
end
end
location.rb
class Location < ActiveRecord::Base
belongs_to :state
has_and_belongs_to_many :profiles
validates_presence_of :address_line_1,
:message => "If you do not wish to add this location,
please click remove."
validates_presence_of :city,
:message => "If you do not wish to add this location,
please click remove."
validates_presence_of :state_id,
:message => "If you do not wish to add this location,
please click remove."
validates_numericality_of :zip,
:allow_nil => false,
:message => "Please enter a zip code consisting of
numbers only"
end
_location.html.erb
<div class="location">
<% new_or_existing = location.new_record? ? ''new'' :
''existing'' %>
<% prefix = "profile[#{new_or_existing}_location_attributes][]"
%>
<% fields_for prefix, location do |location_form| -%>
<p>
Address Line 1: <%= location_form.text_field :address_line_1 %><br
/>
Address Line 2: <%= location_form.text_field :address_line_2 %><br
/>
City: <%= location_form.text_field :city %><br />
State: <%= location_form.select :state_id, State.find(:all).collect
{|p| [ p.name, p.id ] }, { :prompt => "Select a state" } %>
Zip Code: <%= location_form.text_field :zip %><br />
Description: <%= location_form.text_field :description %><br />
<%= link_to_function "remove" ,
"$(this).up(''.location'').remove()"
%>
</p>
<% end -%>
</div>
_form.html.erb
<%= f.hidden_field :id %>
<p>First name: <%= f.text_field :first_name %></p>
<p>Last name: <%= f.text_field :last_name %></p>
<p>Title: <%= f.text_field :title %></p>
<p>Company: <%= f.text_field :company %></p>
<p>User: <%= f.text_field :user_id %></p>
<p>Type: <%= f.text_field :type_id %></p>
<h2>Websites</h2>
<div id="websites">
<%= render :partial => ''website'', :collection =>
@profile.websites %>
</div>
<%= add_website_link "Add a Website" %>
<h2>Numbers</h2>
<div id="numbers">
<%= render :partial => ''number'', :collection =>
@profile.numbers %>
</div>
<%= add_number_link "Add a Number" %>
<h2>Emails</h2>
<div id="emails">
<%= render :partial => ''email'', :collection =>
@profile.emails %>
</div>
<%= add_email_link "Add an Email" %>
<h2>Locations</h2>
<div id="locations">
<%= render :partial => ''location'', :collection =>
@profile.locations
%>
</div>
<%= add_location_link "Add a Location" %>
<h2>Notes</h2>
<div id="notes">
<%= render :partial => ''note'', :collection =>
@profile.notes %>
</div>
<%= add_note_link "Add a Note" %>
profile helper
module ProfilesHelper
def add_website_link(name)
link_to_function name do |page|
page.insert_html :bottom, :websites, :partial =>
''website'' , :object => Website.new
end
end
def add_number_link(name)
link_to_function name do |page|
page.insert_html :bottom, :numbers, :partial => ''number''
, :object
=> Number.new
end
end
def add_email_link(name)
link_to_function name do |page|
page.insert_html :bottom, :emails, :partial => ''email'' ,
:object =>
Email.new
end
end
def add_location_link(name)
link_to_function name do |page|
page.insert_html :bottom, :locations, :partial =>
''location'' , :object => Location.new
end
end
def add_note_link(name)
link_to_function name do |page|
page.insert_html :bottom, :notes, :partial => ''note'' ,
:object =>
Note.new
end
end
end
On Jun 10, 7:59 pm, Jeffrey Lee
<jle...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:> I''ve been working with the Advanced Railes Recipies PDF tutorial
but
> seem to have hit a snag. When adding a HABTM element, locations in
> place of tasks in my usage, the location (address) is added to the
> locations table; however, the join is not added to my
> locations_profiles table (profile_id,location_id). Would I need to do
> something more than just @profile.save in the profiles controller for
> this to be saved properly?
>
> I will post code when I get home but it is essentially the same as the
> tutorial (which doesn''t mention HABTM associations
unfortunetally).
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---