Rails 4 RC1 polymorphic association unable to create -


third update: ok, close, think. creating data , parameters being set in db. changed business controller strong params be:

def business_params       params.require(:business).permit(:name, :description, :address_attributes=>[:line1, :line2, :city, :state, :zip]) 

when edit existing business 2 addresses created reason. 1 empty , 1 complete parameters. so, think i'm close if has final push :).

address model

class address < activerecord::base belongs_to :addressable, polymorphic: true end 

business model:

    class business < activerecord::base       #each business belongs user, through user_id       belongs_to :owner       has_one :address, as: :addressable       accepts_nested_attributes_for :address        # each business has many customers , has many services       has_many :customers       has_many :services      validates :owner_id, presence:true     validates_presence_of :name     #validates_length_of :state, is: 2  end 

business controller:

class businessescontroller < applicationcontroller   before_action :get_owner   before_action :set_business, only: [:show, :edit, :update, :destroy]   #helper_method :sort_column, :sort_direction     def index     @businesses = @owner.businesses   end    def show     #@customer = @business.customers.order(sort_column + " " + sort_direction)   end    def new     @owner = owner.find(params[:owner_id])     @business = @owner.businesses.build     @address = @business.build_address(params[:address])    end    def edit     @address = @business.build_address(params[:address])   end    def create     @business = @owner.businesses.new(business_params)     @address = @business.create_address(params[:address])      respond_to |format|       if @business.save         format.html { redirect_to owner_businesses_url(@owner), notice: 'business created.' }         format.json { render action: 'show', status: :created, location: @business }       else         format.html { render action: 'new' }         format.json { render json: @business.errors, status: :unprocessable_entity }       end     end   end    def update     @address = @business.create_address(params[:address])     respond_to |format|       if @business.update(business_params)         format.html { redirect_to owner_businesses_url(@owner), notice: 'business updated.' }         format.json { head :no_content }       else         format.html { render action: 'edit' }         format.json { render json: @business.errors, status: :unprocessable_entity }       end     end   end    def destroy     @business.destroy     respond_to |format|       format.html { redirect_to owner_businesses_url(@owner) }       format.json { head :no_content }     end   end    private     # use callbacks share common setup or constraints between actions.     def set_business       @business = @owner.businesses.find(params[:id])     end      # never trust parameters scary internet, allow white list through.     def business_params       params.require(:business).permit(:name, :description, :address_attributes=>[:line1, :line2, :city, :state, :zip])     end      def get_owner       @owner = owner.find(params[:owner_id])     end      #def sort_column     #  customer.column_names.include?(params[:sort]) ? params[:sort] : "first_name"         #end      #def sort_direction     #  %w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"     #end   end 

form view:

        <%= form_for([@owner, @business]) |f| %>       <% if @business.errors.any? %>         <div id="error_explanation">           <h2><%= pluralize(@business.errors.count, "error") %> prohibited business being saved:</h2>        <ul>       <% @business.errors.full_messages.each |msg| %>         <li><%= msg %></li>       <% end %>       </ul>     </div>   <% end %>    <div class="field">     <%= f.label :name %><br />     <%= f.text_field :name %>   </div>   <div class="field">     <%= f.label :description %><br />     <%= f.text_area :description %>   </div>    <%= f.fields_for :address |address| %>   <%= p address.object %>   <div class="field">     <%= address.label :line1 %><br>     <%= address.text_field :line1 %>   </div>   <div class="field">     <%= address.label :line2 %><br>     <%= address.text_field :line2 %>   </div>   <div class="field">     <%= address.label :city %><br>     <%= address.text_field :city %>   </div>   <div class="field">     <%= address.label :state %><br>     <%= address.text_field :state %>   </div>   <div class="field">     <%= address.label :zip %><br>     <%= address.number_field :zip %>   </div>    <% end %>    <div class="actions">     <%= f.submit %>   </div> <% end %> 

now i'm getting 2 addresses created. 1 empty, 1 parameters set. there :).

something tells me moron having such difficulty getting polymorphic associations work in rails 4.0 rc1 app i'm working on. being moron aside, did ask stack overflow problems seeing, , reposted question ruby on rails' google group. no answers forthcoming, so, issue becomes first figured out on own.

so that's good, right?

anyway, issue simple. want street/mailing/billing addresses shared across businesses, customers, owners, etc. don't want code 3 different tables doing same. polymorphic association seems way go gather such associations. poke around guidance on , have things model after.

http://kconrails.com/2010/10/19/common-addresses-using-polymorphism-and-nested-attributes-in-rails/>this site useful, though dated. using rails 4. written @ tail end of rails 2 believe. did me shrink time because i'd never done has_one association before , initial problem in rails console, couldn't like:

b = owner.first.businesses.first b.address.create!(params n' stuff) 

i kept getting no_method error create. that's when focused on article above , realized wasn't using create either. using:

b = owner.first.businesses.first b.build_address(params n' stuff) -- wrote @customer.build_address 

the build_association has_one thing. know well. of course, have read docs ahead of time, but, read them during this. can read on @ http://guides.rubyonrails.org/association_basics.html#has_one-association-reference if you're interested.

i follow document pretty closely it's not quite right. "build_address" item in new method of business controller did allow fields_for in form display. but, nothing being written database. empty record being put in address nil values , not attached @ business added for. and, obviously, if business "edited" rather created new, you'd see no address form @ all, figured need build_address method in edit field @ least.

i correct on that, but, still nothing saved.

as go railscasts see ryan has. and, http://http://railscasts.com/episodes/154-polymorphic-association-revised>he has polymorphic stuff great when add comments different models. wasn't directly beneficial wanted here. read lot on stack overflow. checked issues list in rails repository @ github. read rails google group. nothing laid out seeing.

largely because seeing rails 4 issue.

strong parameters built in rails 4. added following address controller account this:

# never trust parameters scary internet, allow white list through. def address_params   params.require(:address).permit(:line1, :line2, :city, :state, :zip) end 

this scaffold make naturally in rails 4 if used rails g scaffold this. strong parameters replaces attr_accessible in model previous versions of rails. model reference polymorphic association address , addressable , business added has_one :address, as: addressable accepts_nested_attributes_for :address. that's good, still nothing being saved. added address_params hash appliction_controller.rb.

i realize i'm being stupid. addition of address taking place in business controller , never see params hash. in application_controller.rb nothing changed. couldn't that.

i see params being passed in log, , insert attempted, unpermitted params reference "address" keeps showing.

i'm asking @ point , trying tweak it.

i see https://github.com/rails/strong_parameters#nested-parameters> section @ github in strong parameters repository. don't understand why accepts_nested_attributes_for wouldn't me, go business controller , adjust params hash there this:

# never trust parameters scary internet, allow white list through. def business_params   params.require(:business).permit(:name, :description, :address_attributes => [:line1, :line2, :city, :state, :zip]) end 

one of articles read said has_one association passes :address_attributes through, put there. things different. data still not being saved, i'm getting no unpermitted errors. , still no answers @ sites.

i decide tweak new, edit, create , update methods.

in new , edit had:

@business.build_address 

i changed in new , edit , added create , update following:

@business.build_address(params[:address]) -- note, :address_attributes appears work there. 

now data saving. fields entering db. problem 2 were. 1 empty , 1 complete on every new , every update. so, remove code above create , update methods in business controller. have 1 address created. correctly. feeling myself, open business edit address , blank address form. nothing being passed form view.

so, change edit method in business controller this:

@business.address ||= @business.build_address(params[:address])

this says if there @business.address, show it, otherwise @business.address built.

now i'm rolling. see saved address when edit form. edit address. edit saved , shows again. old address associated remains. addressable_id changed nil , new address record written. not want. still no coming sites. nothing in log @ all.

i think myself update method should used here. add following line update method of business controller:

@business.address.update(params[:address])

no behavior change, log shows new unpermitted parameter.

it shows "id" unpermitted. so, change business controller params hash read:

# never trust parameters scary internet, allow white list through. def address_params   params.require(:address).permit(:id, :line1, :line2, :city, :state, :zip) end 

and on that, things work. can create business address. in fact, if don't fill in address, address created (given no validations @ point). can update address, complete or empty, , updates existing record. works. i'm not sure best or cleanest way, i'll keep looking.

one issue exists in if manually delete created address associated business , try edit business, update method added above throws error given there no record update. can live without that. think ok creating record every business (and user, owner, customer, etc.) if empty , allowing delete through association rather directly.

but may tweak code find way create complete address , not write empty.

in case, things kind of work @ present.

i'd love hear if there's can improve or should change.

for now, move next thing.


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -