Search code examples
ruby-on-railsformsnested-resources

Forms and nested resources in rails


I have 4 models Users, Clients, invoices and Items

Currently a user can click on a client and see all the invoices from that client. However when he chooses to create a new invoice, the new invoice is already assigned to a client. I also want the ability for the users to create a new invoice and to choose a client from a list or make a new one.

Routes & Models

devise_for :users
resources :invoices, only: [:new]
resources :clients do
resources :invoices, shallow: true
end

class User < ActiveRecord::Base
has_many :invoices
has_many :clients

class Client < ActiveRecord::Base
has_many :invoices
has_many :items, through: :invoices

class Invoice < ActiveRecord::Base
belongs_to :client
has_many :items, :dependent => :destroy

class Item < ActiveRecord::Base
belongs_to :invoice
belongs_to :client

I added the line resources :invoices, only: [:new] to routes.rb file and <%= link_to 'New Invoice', new_invoice_path(@invoice) %> to aplication.html.erb

However I have set up my new action to work only when creating an invoice on the route /clients/:client_id/invoices/new

invoicesController

def new
 @client = Client.find(params[:client_id])
 @invoice = @client.invoices.new
end

And my form

<%= simple_form_for [@client, @invoice] do |f| %>

If I change my controllers new action to

def new
 @invoice = Invoice.new
end

I get undefined method invoices_path for # I know this is coming from the way I set up my form

How can I make both routes work off of the one controller action? Should I have 2 forms?


Solution

  • you also need to enable :create in routes (where form_for will link to via the post method) and have a controller action

    def create
    

    handling the input of the form. otherwise it will not work.