bradpotts
bradpotts

Reputation: 329

form_for can't get edit/update and show/new working together?

My form_for started out like this.

<%= form_for([@memberlisting.membercontact, @memberlisting], url: backend_membercontact_memberlistings_path) do |f| %>

I had a problem with edit/updates with a routing error.

No route matches [PATCH] "/backend/membercontacts/1/memberlistings"

Through another question there was a fix with method: :patch plus backend_membercontact_memberlisting(s)_path removed the s and I can update things.

<%= form_for([@memberlisting.membercontact, @memberlisting], url: backend_membercontact_memberlisting_path, method: :patch) do |f| %>

Now show/new is giving out error where it didn't before.

No route matches {:action=>"show", :controller=>"backend/memberlistings", :membercontact_id=>"1"} missing required keys: [:id]

I'm think putting method patch at the end is causing the above error, but how can I get both show/new + edit/update to work?

Some additional information

routes.rb

# Application Client Backend
namespace :backend do
    # Member Routes
    resources :membercontacts do
        resources :memberaddresses
        resources :memberlistings
    end
end

backend/memberlisting.rb

class Backend::Memberlisting < ActiveRecord::Base

    # Model Relationships
    belongs_to :membercontact

end

backend/membercontact.rb

class Backend::Membercontact < ActiveRecord::Base

    # Model Relationship
    has_many :memberlistings, dependent: :destroy

end

backend/memberlistings_controller.rb

class Backend::MemberlistingsController < ApplicationController

    # Security & Action Filters
    layout '/backend/application.html.erb'
    before_action :set_memberlisting, only: [:show, :edit, :update, :destroy]

    # Member Listing Index
    def index
        membercontact = Backend::Membercontact.find(params[:membercontact_id])
        @memberlistings = membercontact.memberlistings.order('mlcontactname ASC')
    end

    # Detailed Member Listing Profile
    def show
        membercontact = Backend::Membercontact.find(params[:membercontact_id])
        @membercontact = membercontact.memberlistings.find(params[:id])
    end

    # New Member Listing
    def new
        membercontact = Backend::Membercontact.find(params[:membercontact_id])
        @memberlisting = membercontact.memberlistings.build
        respond_to do |format|
            format.html # new.html.erb
            format.xml  { render :xml => @membercontact }
        end
    end

    # Edit Member Listing
    def edit
        membercontact = Backend::Membercontact.find(params[:membercontact_id])
        @memberlisting = membercontact.memberlistings.find(params[:id])
    end

    # Create Member Listing Action
    def create
        @membercontact = Backend::Membercontact.find(params[:membercontact_id])
        @memberlisting = @membercontact.memberlistings.create(memberlisting_params)
        respond_to do |format|
        if @memberlisting.save
            format.html { redirect_to backend_membercontact_memberlistings_path, notice: 'Address for Membercontact was Successfully Created.' }
            format.json { render action: 'show', status: :created, location: @memberlisting }
            else
                format.html { render action: 'new' }
                format.json { render json: @memberlisting.errors, status: :unprocessable_entity }
            end
        end
    end

    # Update Member Listing Action
    def update
        respond_to do |format|
        if @memberlisting.update(memberlisting_params)
            format.html { redirect_to backend_membercontact_memberlistings_path, notice: 'Address for Membercontact was Successfully Updated.' }
            format.json { head :no_content }
            else
                format.html { render action: 'edit' }
                format.json { render json: @memberlisting.errors, status: :unprocessable_entity }
            end
        end
    end

    # Delete Member Listing Action
    def destroy
        @membercontact = Backend::Membercontact.find(params[:membercontact_id])
        @memberlisting = @membercontact.memberlistings.find(params[:id])
        @memberlisting.destroy
        respond_to do |format|
            format.html { redirect_to backend_membercontact_memberlistings_path, notice: 'Address for Membercontact was Successfully Deleted.'  }
            format.json { head :no_content }
        end
    end

    private

    def set_memberlisting
        @memberlisting = Backend::Memberlisting.find(params[:id])
    end

    def memberlisting_params
        params.require(:backend_memberlisting).permit(:mlcontactname, :mlcompanyname, :mladdressline1, :mladdressline2, :mlcity, :mlprovince, :mlpostalcode, :mlphone, :mlwebsite, :mlemail, :membercontact_id, :account_id)
    end

end

Routes Rake

backend_membercontact_memberlistings_path       GET /backend/membercontacts/:membercontact_id/memberlistings(.:format)  backend/memberlistings#index
                                                POST    /backend/membercontacts/:membercontact_id/memberlistings(.:format)  backend/memberlistings#create
new_backend_membercontact_memberlisting_path    GET /backend/membercontacts/:membercontact_id/memberlistings/new(.:format)  backend/memberlistings#new
edit_backend_membercontact_memberlisting_path   GET /backend/membercontacts/:membercontact_id/memberlistings/:id/edit(.:format) backend/memberlistings#edit
backend_membercontact_memberlisting_path        GET /backend/membercontacts/:membercontact_id/memberlistings/:id(.:format)  backend/memberlistings#show
                                                PATCH   /backend/membercontacts/:membercontact_id/memberlistings/:id(.:format)  backend/memberlistings#update
                                                PUT /backend/membercontacts/:membercontact_id/memberlistings/:id(.:format)  backend/memberlistings#update
                                                DELETE  /backend/membercontacts/:membercontact_id/memberlistings/:id(.:format)  backend/memberlistings#destroy

I like to keep everything nested the way it is. I can't figure out why crud functions are giving me problems, if I take out the patch method it won't update but when I put the patch method in it won't create a new or show record b/c of missing id.

Upvotes: 0

Views: 417

Answers (1)

Rich Seviora
Rich Seviora

Reputation: 1809

Your form_for has the URL option specified, which means that it's always going to route to that path using the objects provided in the records argument. The path you've listed is compatible with existing objects, but it does not match a new object, which doesn't yet have an ID.

You also can't specify PATCH, because it's always going to use that even when that method doesn't exist.

You also need to include your namespace in the form_for records argument, so it would look pretty close to the following:

<%= form_for([:backend, @memberlisting.membercontact, @memberlisting]) do |f| %>

Give that a shot and see if it works. You can read more about the form_for helper here.

Upvotes: 1

Related Questions