Refuse particle from another model

I have a rail application that simulates a house. There is a model of the house, which has many parameters and has_many rooms . The room has a house_id and a name. I also used http://github.com/ryanb/complex-form-examples to add a lot of lights and small_appliances to the room. An example of complex form uses RJS and partial to accomplish this.

There is a controller called a calculator that users will use to access the application. When the submit button on the calculator is pressed, it redirects to the add_rooms page (located on the page app/views/calculator/add_rooms.html.erb ), where the user can add rooms to the house. The add_rooms page uses a partial value from app/views/rooms/_room_form.html.erb . I was not able to display this since the rails are always looking for things in the app / views / calculator folder.

How can I display this? Also note that when saving the room I need to save the house ID.

Here is all the relevant code (hopefully):

Update

If I comment on two add_child_link . The page is displayed. However, when I click the submit button, I get a new error message:

  ActiveRecord :: AssociationTypeMismatch in CalculatorController # add_room

 SmallAppliance (# 49096610) expected, got Array (# 1560620)

 RAILS_ROOT: C: / Users / ryan / Downloads / react
 Application Trace |  Framework Trace |  Full trace

 C: /InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/associations/association_proxy.rb: 263: in `raise_on_type_mismatch '
 C: /InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/associations/association_collection.rb: 320: in `replace '
 C: /InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/associations/association_collection.rb: 320: in `each '
 C: /InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/associations/association_collection.rb: 320: in `replace '
 C: /InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/associations.rb: 1322: in `small_appliances = '
 C: /InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb: 2744: in `send '
 C: /InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb: 2744: in `attributes = '
 C: /InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb: 2740: in `each '
 C: /InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb: 2740: in `attributes = '
 C: /InstantRails/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb: 2438: in `initialize '
 C: /Users/ryan/Downloads/react/app/controllers/calculator_controller.rb: 31: in `new '
 C: /Users/ryan/Downloads/react/app/controllers/calculator_controller.rb: 31: in `add_room '

If I remove the small_application part, the same will happen for light. I think this has something to accepts_nested_attributes_for with accepts_nested_attributes_for in the room model. I have added the code below. I also added house.rb code.

application / models / room.rb

 class Room < ActiveRecord::Base 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 

application / models / house.rb

 class House < ActiveRecord::Base has_many :rooms # validation code not included def add_room(room) rooms << room end end 

application / 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 @house = House.find(params[:id]) @room = Room.new(params[:room]) respond_to do |format| if @room.save @house.add_room(@room) @house.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 /> <%= button_to "Continue to report", :action => "report", :id => @house %> </div> 

app / views / rooms / _room_ form.html.erb

 <% form_for :room, :url => { :action => :add_room, :id => @house } do |form| %> <%= form.error_messages %> <p> <%= form.label :name %><br /> <%= form.text_field :name %> </p> <h3>Lights</h3> <% 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.fields_for :small_appliances do |sm_appl_form| %> <%= render :partial => 'rooms/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

+3
source share
3 answers

Very strange - if you write <%= render :partial => 'room_form' %> , than the rails will consider it to be app/views/calculator/_room_form.html.erb , but in the case of <% = render: partial => 'rooms / room_form'%> he will assume that this is app/views/rooms/_room_form.html.erb

Keep track of your magazine - there you will see which parts were displayed

+3
source

I know this question is old, but I ran into the same problem and was able to solve it.

To be specific, I also followed examples of complex forms of ryan baht.

My form was not rendering with the same error:

 undefined method `reflect_on_association' for NilClass:Class 

I commented on the add_child_link helper and the processed form, but after submitting, I got:

 ChildModel expected, got Array 

After many corrections, I made one simple change that fixed everything:

 -- form_for :project ++ form_for @project 

That's right, just switching the character for the instance variable made it all work.

Hope this helps anyone stuck

+1
source

The problem is that you do not have a room object defined when you try to add a child link.

 render :partial => 'rooms/room_form', :object => Room.new 
0
source

All Articles