I'm experimenting with routing and namespaces.
When implementing a form with <%= form_with model: [@user, @address] do |form| %>
i receive this error undefined method 'customer_user_customer_addresses_path'
This is the routing schema
namespace :customer do
resources :users do
resource :contact
resources :addresses
end
end
resolve('Customer::Contact') {
[:customer, :user, :contact]
}
All routes printed by rails routes
command are as expected.
customer_user_addresses GET /customer/users/:user_id/addresses(.:format) customer/addresses#index
POST /customer/users/:user_id/addresses(.:format) customer/addresses#create
new_customer_user_address GET /customer/users/:user_id/addresses/new(.:format) customer/addresses#new
edit_customer_user_address GET /customer/users/:user_id/addresses/:id/edit(.:format) customer/addresses#edit
customer_user_address GET /customer/users/:user_id/addresses/:id(.:format) customer/addresses#show
PATCH /customer/users/:user_id/addresses/:id(.:format) customer/addresses#update
PUT /customer/users/:user_id/addresses/:id(.:format) customer/addresses#update
DELETE /customer/users/:user_id/addresses/:id(.:format) customer/addresses#destroy
Customer::UsersController
i was able to access all crud operations for the users resourcesCustomer::ContactsController
i was able to access all crud operations but i had to add the resolve directive in order to make the routes generated correctly resolve('Customer::Contact') {
[:customer, :user, :contact]
}
When implementing the Customer::AddressesController
i can't figure out a way to make form_with requesting the correct path.
This is the controller action
def new
@breadcrumbs = []
@user = Customer::User.find(params[:user_id])
@address = @user.addresses.build
end
This is the new template
<%= form_with model: [@user, @address] do |form| %>
When i navigate to the new action i get this error undefined method 'customer_user_customer_addresses_path'
In order to make it working i had to pass an url parameter with the correct path: <%= form_with model: [@user, @address], url: customer_user_addresses_path(@user) do |form| %>
.
What convention am i missing? is there any way to omit the url parameter?
Repository: https://github.com/LuigiDeCosmis/GestionaleTest
Template to check is under customer/addresses/new.html.erb
Where did customer_
prefix come from?
You are getting customer_
prefix both for user
and address
in your error message
undefined method 'customer_user_customer_addresses_path'
because you are trying to build you path based on models - while both of your User
/ Address
models are placed in Customer
namespace.
To be specific - customer_
prefix came from here:
Customer::User.model_name.param_key
# => "customer_user"
Customer::Address.model_name.param_key
# => "customer_address"
This is how it's trying to parse it: https://github.com/rails/rails/blob/af773ae44a1ae465cc0d19b1e8bf3fc731221ef0/actionview/lib/action_view/helpers/form_helper.rb#L756
What convention am i missing?
I can see no reason why you should namespace your models like that.
If you want your users to be either customer
/ admin
or anything else - you should rather use STI approach
https://api.rubyonrails.org/classes/ActiveRecord/Inheritance.html
https://medium.com/nyc-ruby-on-rails/single-table-inheritance-sti-ruby-on-rails-basics-2a08c81e50af
Is there any way to omit the url parameter?
Yes. After you get rid of Customer
namespace for models you will be able to see in your routes something like:
customer_user_addresses
This is an example of routes which can be set up with model option.
Hope that helps! Good luck!