I have a rails application that models a house. house contains rooms and rooms have nested attributes for light and small_appliance. I have a calculator controller, which is how end users will access the application.
My problem is that I can't get the partial for adding rooms to render and submit correctly from calculator. The initial page lets the user enter house information, which is saved using save_house when submit is clicked. This also redirects the user to the add_rooms page, where they can add rooms to the house.
add_rooms displays correctly, but when I click submit, I get this error:
RuntimeError in Calculator#add_room
Showing app/views/calculator/add_rooms.html.erb where line #2 raised:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
Extracted source (around line #2):
1: <div id="addRooms">
2: <p>House id is <%= #house.id %></p>
3:
4: <h3>Your rooms:</h3>
5: <% if #house.rooms %>
RAILS_ROOT: C:/Users/ryan/Downloads/react
Application Trace | Framework Trace | Full Trace
C:/Users/ryan/Downloads/react/app/views/calculator/add_rooms.html.erb:2:in `_run_erb_app47views47calculator47add_rooms46html46erb'
C:/Users/ryan/Downloads/react/app/controllers/calculator_controller.rb:36:in `add_room'
C:/Users/ryan/Downloads/react/app/controllers/calculator_controller.rb:33:in `add_room'
This is odd to me, because when add_rooms first renders, it shows the house_id. I don't understand why it isn't passed after the form is submitted.
Here's the code:
app/models/room.rb
class Room < ActiveRecord::Base
# schema { name:string, house_id:integer }
belongs_to :house
has_many :lights, :dependent => :destroy
has_many :small_appliances, :dependent => :destroy
validates_presence_of :name
accepts_nested_attributes_for :lights, :reject_if => lambda { |a| a.values.all?(&:blank?) }, :allow_destroy => true
accepts_nested_attributes_for :small_appliances, :reject_if => lambda { |a| a.values.all?(&:blank?) }, :allow_destroy => true
end
app/models/house.rb
class House < ActiveRecord::Base
has_many :rooms
# validation code not included
def add_room(room)
rooms << room
end
end
app/controllers/calculator_controller.rb
class CalculatorController < ApplicationController
def index
end
def save_house
#house = House.new(params[:house])
respond_to do |format|
if #house.save
format.html { render :action => 'add_rooms', :id => #house }
format.xml { render :xml => #house, :status => :created, :location => #house }
else
format.html { render :action => 'index' }
format.xml { render :xml => #house.errors, :status => :unprocessable_entity }
end
end
end
def add_rooms
#house = House.find(params[:id])
#rooms = Room.find_by_house_id(#house.id)
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid house #{params[:id]}")
flash[:notice] = "You must create a house before adding rooms"
redirect_to :action => 'index'
end
def add_room
#room = Room.new(params[:room])
#house = #room.house
respond_to do |format|
if #room.save
flash[:notice] = "Room \"#...#room.name}\" was successfully added."
format.html { render :action => 'add_rooms' }
format.xml { render :xml => #room, :status => :created, :location => #room }
else
format.html { render :action => 'add_rooms' }
format.xml { render :xml => #room.errors, :status => :unprocessable_entity }
end
end
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid house #{params[:id]}")
flash[:notice] = "You must create a house before adding a room"
redirect_to :action => 'index'
end
def report
flash[:notice] = nil
#house = House.find(params[:id])
#rooms = Room.find_by_house_id(#house.id)
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid house #{params[:id]}")
flash[:notice] = "You must create a house before generating a report"
redirect_to :action => 'index'
end
end
app/views/calculator/add_rooms.html.erb
<div id="addRooms">
<p>House id is <%= #house.id %></p>
<h3>Your rooms:</h3>
<% if #house.rooms %>
<ul>
<% for room in #house.rooms %>
<li>
<%= h room.name %> has <%= h room.number_of_bulbs %>
<%= h room.wattage_of_bulbs %> watt bulbs, in use for
<%= h room.usage_hours %> hours per day.
</li>
<% end %>
</ul>
<% else %>
<p>You have not added any rooms yet</p>
<% end %>
<%= render :partial => 'rooms/room_form' %>
<br />
</div>
<%= button_to "Continue to report", :action => "report", :id => #house %>
app/views/rooms/_room_form.html.erb
<% form_for :room, #house.rooms.build, :url => { :action => :add_room } do |form| %>
<%= form.error_messages %>
<p>
<%= form.label :name %><br />
<%= form.text_field :name %>
</p>
<h3>Lights</h3>
<% form.object.lights.build if form.object.lights.empty? %>
<% form.fields_for :lights do |light_form| %>
<%= render :partial => "light", :locals => { :form => light_form } %>
<% end %>
<p class="addLink"><%= add_child_link "[+] Add new light", form, :lights %></p>
<h3>Small Appliances</h3>
<% form.object.small_appliances.build if form.object.small_appliances.empty? %>
<% form.fields_for :small_appliances do |sm_appl_form| %>
<%= render :partial => "small_appliance", :locals => { :form => sm_appl_form } %>
<% end %>
<p class="addLink"><%= add_child_link "[+] Add new small appliance", form, :small_appliances %></p>
<p><%= form.submit "Submit" %></p>
<% end %>
application_helper.rb
module ApplicationHelper
def remove_child_link(name, form)
form.hidden_field(:_delete) + link_to_function(name, "remove_fields(this)")
end
def add_child_link(name, form, method)
fields = new_child_fields(form, method)
link_to_function(name, h("insert_fields(this, \"#{method}\", \"#{escape_javascript(fields)}\")"))
end
def new_child_fields(form_builder, method, options = {})
options[:object] ||= form_builder.object.class.reflect_on_association(method).klass.new
options[:partial] ||= method.to_s.singularize
options[:form_builder_local] ||= :form
form_builder.fields_for(method, options[:object], :child_index => "new_#{method}") do |form|
render(:partial => options[:partial], :locals => { options[:form_builder_local] => form })
end
end
end
Thanks,
Ryan
Out of curiosity why not have house accept nested attributes for rooms. This would make your controller code simpler, as adding many rooms, lights and small appliances is as simple as just doing #house.update_attributes(params[:house]). However this is not an answer that helps, as you would still have your current problems if you made the change.
Your first error comes from the first line of app/views/calculator/_room_form.html.erb
<% form_for :room, :url => { :action => :add_room, :id => #house } do |form| %>
You're not giving form_for an object so the new_child_fields method called by add_child
_link is trying to call reflect_on_association on the Nil class.
The solution is change the line to
<% form_for :room, #house.rooms.build, :url => { :action => :add_room } do |form| %>
This lets you simplify your controller, because a room associated with a house is already being passed to it.
def add_room
#room = Room.new(params[:room])
#house = #room.house
respond_to do |format|
if #room.save
flash[:notice] = "Room \"#...#room.name}\" was successfully added."
format.html { render :action => 'add_rooms' }
format.xml { render :xml => #room, :status => :created, :location => #room }
else
format.html { render :action => 'add_rooms' }
format.xml { render :xml => #room.errors, :status => :unprocessable_entity }
end
end
rescue ActiveRecord::RecordNotFound
logger.error("Attempt to access invalid house #{params[:id]}")
flash[:notice] = "You must create a house before adding a room"
redirect_to :action => 'index'
end
I believe your second error is the same problem. However because you're calling a has_many accessor instead of getting a nil being generated, you're passing an empty array, which explains the difference in error messages. Again the solution is to build a light and small appliance before rendering if none exist yet.
<h3>Lights</h3>
<% form.object.lights.build if form.object.lights.empty? %>
<% form.fields_for :lights do |light_form| %>
<%= render :partial => 'rooms/light', :locals => { :form => light_form } %>
<% end %>
<p class="addLink"><%= add_child_link "[+] Add new light", form, :lights %></p>
<h3>Small Appliances</h3>
<% form.object.small_appliances.build if form.object.small_appliances.empty? %>
<% form.fields_for :small_appliances do |sm_appl_form| %>
<%= render :partial => 'rooms/small_appliance', :locals => { :form => sm_appl_form } %>
<% end %>
Your new error comes from this:
def new_child_fields(form_builder, method, options = {})
options[:object] ||= form_builder.object.class.reflect_on_association(method).klass.new
# specifically this line.
options[:partial] ||= method.to_s.singularize
options[:form_builder_local] ||= :form
form_builder.fields_for(method, options[:object], :child_index => "new_#{method}") do |form|
render(:partial => options[:partial], :locals => { options[:form_builder_local] => form })
end
end
new_child_fields is assuming that the _light partial is in the app/views/calculators folder
The solution is to either move the light and small_appliances partials to this folder or modify your helper methods to accept a partial option.
Related
I have a form which allows a user to invite multiple people via adding emails in a comma separated list. In my "Participant" model, I have a call to validate the uniqueness of the email entered (scoped by "project_id"). In the model validation, it gives a place to explain the error (message), but I can't get that error to show up on my form if the validation fails.
If a user enters the email of a person that has already been added, how can I get the errors message to render?
participant.rb
class Participant < ActiveRecord::Base
validates :email, uniqueness: {case_sensitive: false, scope: :project_id, message: "Looks like you\'ve already added this person."}
end
participant_controller.rb
def new_participant
#new_participants = Participant.new
#participants = Participant.where(project_id: #project.id).includes(:user)
#template = Template.find(#project.template_id)
#address = Address.where(project_id: #project.id).first
#food = ProjectRestriction.where(project_id: #project.id)
end
def add_participant
#added_by = User.find(current_user.id)
#new_participants = params[:new_participants][:email].split(/,\s*/)
#new_participants.each do |t|
newpart = Participant.new(:email => t, :project_id => #project.id, :level => 4,
:participant_cat_id => 2, :last_updated_by => current_user.id, :added_by => current_user.id, :status => 'unseen')
respond_to do |format|
if newpart.save
ProjectMailer.notify_recipient(newpart, #project, #added_by, #participant_invite ).deliver_later
self.response_body = nil
redirect_to participants_path(p: #project.id, w: 'recipient')
else
format.html { redirect_to new_participant_path(p: #project.id)}
format.json { render json: #new_participants.errors, status: :unprocessable_entity }
end
end
end
end
form
<%= form_for :new_participants, url: add_participant_path( :p => #project.id), html: { :multipart => true, :class=> "form-horizontal", id: "basicForm" } do |f| %>
<% if #new_participants.errors.any? %>
<h2>OOPS!</h2>
<ul>
<% #new_participants.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul></div>
<% end %>
<div class="form-group ">
<label class="form-label dk-aqua"> Email: <span class="asterisk">*</span></label>
<%= f.text_field :email, :autofocus => true, :required => true, :maxlength => 55, :placeholder => 'Email(s)', :class => 'form-control' %>
</div>
<%= f.submit 'INVITE', :class => 'btn btn-aqua btn-lg btn-block',
:style => 'margin-bottom:-5px' %>
<% end %>
Your main issues are:
you are creating a respond block for each email in the request. 1 request = 1 response.
The objects in stored in memory in #new_participants are not actually saved.
In your views your are treating #new_participants as if it where a single resource.
Pay attention to pluralization when naming routes, variables and actions.
def add_participants
#added_by = User.find(current_user.id)
#new_participants = params[:new_participants][:email].split(/,\s*/)
#new_participants.map do |email|
newpart = Participant.new(
:email => email,
:project_id => #project.id,
:level => 4,
:participant_cat_id => 2,
:last_updated_by => current_user.id,
:added_by => current_user.id,
:status => 'unseen'
)
if newpart.save
ProjectMailer.notify_recipient(newpart, #project, #added_by, #participant_invite ).deliver_later
end
new_part
end
#invalid = #new_participants.reject(&:valid?)
if #invalid.any?
respond_to do |format|
format.html { redirect_to new_participant_path(p: #project.id)}
format.json { render json: #new_participants.map(&:errors), status: :unprocessable_entity }
end
else
respond_to do |format|
redirect_to participants_path(p: #project.id, w: 'recipient')
end
end
end
<ul>
<% #new_participants.each |p| %>
<% p.errors.messages.each do |msg| %>
<li><%= msg %></li>
<% end if p.errors.any? %>
<% end %>
</ul>
Not really any error messages, just no file uploaded!
Please help!!!!
everything get created and is fine apart from the file upload.
Models:
class Assets < ActiveRecord::Base
belongs_to :assetable, :polymorphic => true
delegate :url, :to => :attachment
attr_accessible :asset, :asset_file_name
end
class Video < ActiveRecord::Base
attr_accessible :body, :title, :url, :covers, :assets
has_many :covers, :as => :assetable, :class_name => "Video::Cover", :dependent => :destroy
accepts_nested_attributes_for :covers, :allow_destroy => true
class Video::Cover < Assets
has_attached_file :attachment, :styles => { :small => "300x0>", :large => "800x0>" }
end
end
video controller:
class VideosController < ApplicationController
#load_and_authorize_resource
# GET /videos
# GET /videos.xml
def index
#videos = Video.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #videos }
end
end
# GET /videos/1
# GET /videos/1.xml
def show
#video = Video.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #video }
end
end
# GET videos/new
# GET /videos/new.xml
def new
#video = Video.new
1.times do #video.covers.build end
#40.times do #video.images.build end
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #video }
end
end
# GET /collections/1/edit
def edit
#video = Video.find(params[:id])
1.times do #video.covers.build end
#1.times do #video.images.build end
end
# POST /videos
# POST /videos.xml
def create
#video = Video.new(params[:video])
respond_to do |format|
if #video.save
format.html { redirect_to(#video, :notice => 'Video was successfully created.') }
format.xml { render :xml => #video, :status => :created, :location => #video }
else
format.html { render :action => "new" }
format.xml { render :xml => #video.errors, :status => :unprocessable_entity }
end
end
end
# PUT /videos/1
# PUT /videos/1.xml
def update
#video = Video.find(params[:id])
respond_to do |format|
if #video.update_attributes(params[:video])
format.html { redirect_to(#video, :notice => 'Video was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #video.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /videos/1
# DELETE /videos/1.xml
def destroy
#video = Video.find(params[:id])
#video.destroy
respond_to do |format|
format.html { redirect_to(videos_url) }
format.xml { head :ok }
end
end
end
Views:
form
<div id="form_bk">
<div id="field_left">
<%= form_for #video, :html => {:multipart => true} do |f| %>
<% if #video.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#video.errors.count, "error") %> prohibited this video from being saved:</h2>
<ul>
<% #video.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div id="cover">
<br />
<h2>Cover Image</h2>
<%= f.fields_for :covers do |cover_image| %>
<% if cover_image.object.new_record? %>
<p><%= cover_image.file_field :attachment %></p>
<% end %>
<% end %>
<%= f.fields_for :covers do |cover_image| %>
<% unless cover_image.object.new_record? %>
<br />
<p>
<%=image_tag cover_image.object.url(:small) %><br />
<br /> Delete cover <%= cover_image.check_box :_destroy %><br /><br />
</p>
<% end %>
<% end %>
</div>
<div id="form_right">
<div class="field">
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :body %><br />
<%= f.text_area :body %>
</div></div>
<div class="field">
<%= f.label :url %><br />
<%= f.text_area :url %>
</div></div>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<br />
</div>
Index view
<% #videos.each do |video| %>
<div class="video">
<%- video.covers.each do |cover| %>
<div class="video_cover"><%=link_to image_tag (cover.url(:small)), video %></div>
<% end %>
<div class="video_title">
<%=link_to video.title, video %>
<%= video.body %>
<%= link_to 'Show', video %>
<%= link_to 'Edit', edit_video_path(video) %>
<%= link_to 'Destroy', video, :confirm => 'Are you sure?', :method => :delete %>
</div>
</div>
<% end %>
<br /><br /><br />
<%= link_to 'New Video', new_video_path %>
<%= debug #videos %>
I'm a newbie with rad rails. I wanted to write at same time in two table from one form.
I have a table machine (with nom and role as column) and a table ipvfour (with machine_id and ip as column).
So I created in models the relation has-and-belongs-to-many.
But when I'm trying to add a new machine if failed with
unknown attribute: ip
I don't really understand why, can someone help me please ?
machine.controllers:
def create
#machine = Machine.new(params[:machine])
ipvfour = #machine.ip.create(params[:ip])
respond_to do |format|
if #machine.save && ipvfour.save
flash[:notice] = 'Machine was successfully created.'
format.html { redirect_to(#machine) }
format.xml { render :xml => #machine, :status => :created, :location => #machine }
else
format.html { render :action => "new" }
format.xml { render :xml => #machine.errors, :status => :unprocessable_entity }
end
end
end
new.html.erb (machine)
New machine
'form', :locals => { :f_machine => f_machine } %>
_form.html.erb (machine)
<% f_machine.fields_for :ip do |f_ip| %>
<%= render :partial => 'ipvfours/form', :locals => { :f_ip => f_ip } %>
<% end %>
_form.html.erb (ipvfours)
<%= f_ip.label :ip %><br />
<%= f_ip.text_field :ip %>
The page to add a machine is correclty displayed with all fields but it seems that write in db failed due to .... I hope that someone will be able ti help me.
Thanks in advance.
EDIT:
You can edit any model in any controller if you want. There's a magic trick called
accepts_nested_attributes_for (google it!)
Your code should look like:
In your Controller:
def new
# .... your code ....
# create empty machine
#machine = Machine.new
# add one empty ip
#machine.ipvfours.build
# .... your code ....
end
def create
# fill machine and ipvfours directly
#machine = Machine.new(params[:machine])
respond_to do |format|
if #machine.save
flash[:notice] = 'Machine was successfully created.'
format.html { redirect_to(#machine) }
format.xml { render :xml => #machine, :status => :created, :location => #machine }
else
format.html { render :action => "new" }
format.xml { render :xml => #machine.errors, :status => :unprocessable_entity }
end
end
end
In your view:
new.html.erb
<% form_for(#machine) do |f_machine| %>
<%= render :partial => 'form', :locals => { :f_machine => f_machine } %>
<%= f_machine.submit 'Create' %>
<% end %>
<%= link_to 'Back', machines_path %>
_form.html.erb (machine)
<%= f_machine.error_messages %>
<% f_machine.fields_for :ipvfours do |f_ip| %>
<%= render :partial => 'ipvfours/form', :locals => { :f_ip => f_ip } %>
<% end %>
_form.html.erb (ipvfours)
<%= f_ip.label :ip %>
<br />
<%= f_ip.text_field :ip %>
In your Model:
Machine model
class Machine < ActiveRecord::Base
has_many :ipvfours, :dependent => :destroy
accepts_nested_attributes_for :ipvfours
end
best regards
simon
I had hard time to figure out why I've been getting "unknown action" error message when I was do some editing:
Unknown action
No action responded to 11. Actions: bin, create, destroy, edit, index, new, observe_new, show, tag, update, and vote
you can see that Rails did mention each action in the above list - update. And in my form, I did specify action = "update".
I wonder if some friends could kindly help me with the missing links...
here is the code:
edit.rhtml
<h1>Editing tip</h1>
<% form_tag :action => 'update', :id => #tip do %>
<%= render :partial => 'form' %>
<p>
<%= submit_tag_or_cancel 'Save Changes' %>
</p>
<% end %>
_form.rhtml
<%= error_messages_for :tip %>
<p><label>Title<br/>
<%= text_field :tip, :title %></label></p>
<p><label>Categories<br/>
<%= select_tag('categories[]', options_for_select(Category.find(:all).collect {|c| [c.name, c.id] }, #tip.category_ids), :multiple => true ) %></label></p>
<p><label>Abstract:<br/>
<%= text_field_with_auto_complete :tip, :abstract %></label></p>
<p><label>Name: <br/>
<%= text_field :tip, :name %></label></p>
<p><label>Link: <br/>
<%= text_field :tip, :link %></label></p>
<p><label>Content<br/>
<%= text_area :tip, :content, :rows => 5 %></label></p>
<p><label>Tags <span>(space separated)</span><br/>
<%= text_field_tag 'tags', #tip.tag_list, :size => 40 %></label></p>
class TipsController < ApplicationController
before_filter :authenticate, :except => %w(index show)
# GET /tips
# GET /tips.xml
def index
#tips = Tip.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #tips }
end
end
# GET /tips/1
# GET /tips/1.xml
def show
#tip = Tip.find_by_permalink(params[:permalink])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #tip }
end
end
# GET /tips/new
# GET /tips/new.xml
def new
#tip = session[:tip_draft] || current_user.tips.build
end
def create
#tip = current_user.tips.build(params[:tip])
#tipMail=params[:email]
#if tipMail
# TipMailer.deliver_email_friend(params[:email], params[:name], tip)
# flash[:notice] = 'Your friend has been notified about this tip'
#end
#tip = current_user.tips.build(params[:tip])
#tip.categories << Category.find(params[:categories]) unless params[:categories].blank?
#tip.tag_with(params[:tags]) if params[:tags]
if #tip.save
flash[:notice] = 'Tip was successfully created.'
session[:tip_draft] = nil
redirect_to :action => 'index'
else
render :action => 'new'
end
end
def edit
#tip = Tip.find(params[:id])
end
def update
#tip = Tip.find(params[:id])
respond_to do |format|
if #tip.update_attributes(params[:tip])
flash[:notice] = 'Tip was successfully updated.'
format.html { redirect_to(#tip) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #tip.errors, :status => :unprocessable_entity }
end
end
end
def destroy
#tip = Tip.find(params[:id])
#tip.destroy
respond_to do |format|
format.html { redirect_to(tips_url) }
format.xml { head :ok }
end
end
def observe_new
session[:tip_draft] = current_user.tips.build(params[:tip])
render :nothing => true
end
end
the quick answer is that form_tag doesn't support :action as an option, you want to be passing a string as a path in. A slightly longer answer is you shouldn't be using form_tag anyways for a model edit form, you should be using form_for.
what rails are you using? .rhtml is pretty old, rails generators should be giving you .html.erb files. if it is something even remotely recent, you should be able to use
<% form_for #tip do |f| %>
<%= f.label :title, 'Title' %><br />
<%= f.text_field %>
... etc
<% end %>
I get the following error:
ActiveRecord::AssociationTypeMismatch in ContractsController#create
ExchangeRate(#2183081860) expected, got HashWithIndifferentAccess(#2159586480)
Params:
{"commit"=>"Create",
"authenticity_token"=>"g2/Vm2pTcDGk6uRas+aTgpiQiGDY8lsc3UoL8iE+7+E=",
"contract"=>{"side"=>"BUY",
"currency_id"=>"488525179",
"amount"=>"1000",
"user_id"=>"633107804",
"exchange_rate"=>{"rate"=>"1.7"}}}
My relevant model is :
class Contract < ActiveRecord::Base
belongs_to :currency
belongs_to :user
has_one :exchange_rate
has_many :trades
accepts_nested_attributes_for :exchange_rate
end
class ExchangeRate < ActiveRecord::Base
belongs_to :denccy, :class_name=>"Currency"
belongs_to :numccy, :class_name=>"Currency"
belongs_to :contract
end
My view is:
<% form_for #contract do |contractForm| %>
Username: <%= contractForm.collection_select(:user_id, User.all, :id, :username) %> <br>
B/S: <%= contractForm.select(:side,options_for_select([['BUY', 'BUY'], ['SELL', 'SELL']], 'BUY')) %> <br>
Currency: <%= contractForm.collection_select(:currency_id, Currency.all, :id, :ccy) %> <br> <br>
Amount: <%= contractForm.text_field :amount %> <br>
<% contractForm.fields_for #contract.exchange_rate do |rateForm|%>
Rate: <%= rateForm.text_field :rate %> <br>
<% end %>
<%= submit_tag :Create %>
<% end %>
My View Controller:
class ContractsController < ApplicationController
def new
#contract = Contract.new
#contract.build_exchange_rate
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #contract }
end
end
def create
#contract = Contract.new(params[:contract])
respond_to do |format|
if #contract.save
flash[:notice] = 'Contract was successfully created.'
format.html { redirect_to(#contract) }
format.xml { render :xml => #contract, :status => :created, :location => #contract }
else
format.html { render :action => "new" }
format.xml { render :xml => #contract.errors, :status => :unprocessable_entity }
end
end
end
I'm not sure why it's not recognizing the exchange rate attributes?
Thank you
The problem is that accepts_nested_attributes_for :exchange_rate looks for "exchange_rate_attributes" in the params, not "exchange_rate". The fields_for helper will do this for you, but you have to change it to:
<% contractForm.fields_for :exchange_rate do |rateForm|%>