I am trying to learn how to think the way rails expects. It has been a 4+ year struggle and I'm still not there.
I've asked variations on this question so many times now and I still can't decipher a principle I can use to think for myself when it comes to writing paths.
I have models for user and setting. The associations are:
User
has_one :setting, dependent: :destroy
Setting
belongs_to :user
My routes are:
resources :users, shallow: true do
scope module: :users do
resources :settings
end
My Settings controller and views are nested inside a folder called 'users'.
I am trying to add a link to my nav bar that links to my setting show page.
I have tried 20+ different variations, the significant majority of them are guesses. Nothing I think should work does.
When I rake routes, I can see:
users/settings#show PATCH /settings/:id(.:format)
I understand this to mean that I should be able to write:
users_settings_path(@current_user.settings)
I can't.
I have tried:
<%= link_to "Settings", [@current_user, settings_path] %>
I have also tried each of these:
users_settings_path(@current_user.setting)
users_settings_path(@settings)
users_settings_path(setting_url)
users_settings_path(setting_id)
users_setting_path [@current_user, setting_path]
[@current_user, setting]
[@current_user, settings]
[@current_user.settings, settings]
[@current_user.setting, setting]
[@current_user.settings, settings]
In each case, I get an error that says:
undefined method `setting' for nil:NilClass
I think this error message means that the user does not have a setting. However, that error message doesnt make any sense because I have added a line to my users registration controller that says:
class Users::RegistrationsController < Devise::RegistrationsController
def create
super do |user|
if user.persisted?
User::CompleteRegistrationService.call(user: user)
end
end
end
I then have a service class that has:
class User::CompleteRegistration < ActiveRecord::Base
def self.call(user: u)
new(user: user).call
end
def initialize(user: u)
self.user = user
end
def call
Setting::SetupService.call(user: user)
end
private
attr_accessor :user
end
Then I have:
class Setting::SetupService < ActiveRecord::Base
def self.call(user: u)
new(user: user).call
end
def initialize(user: u)
self.user = user
end
def call
setting = Setting.create!(user: user)
# Dashboard.create(profile: profile)
end
private
attr_accessor :user
end
So, I expect that when I create a user, this service class operates to create a setting.
I can't figure out whether I'm writing the link in the nav bar incorrectly (I have tried at least 30 variations on my best guess - so Im not hopeful that I haven't stumbled across the correct formation), or my service class doesnt work to create a setting when a user is created.
Can anyone see where I'm going awry?
I can see in my console that I have a user, but I don't seem to have any Setting instances:
Setting.first
Setting Load (5.2ms) SELECT "settings".* FROM "settings" ORDER BY "settings"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> nil
My logs show an error with the service class method that is in my registrations controller.
The log says:
NameError - uninitialized constant User::CompleteRegistrationService:
app/controllers/users/registrations_controller.rb:9:in `block in create'
devise (4.2.0) app/controllers/devise/registrations_controller.rb:18:in `create'
app/controllers/users/registrations_controller.rb:7:in `create'
The problem is that I don't understand how to make sense of the logs. Uninitialised Constant means that a User has not been initialised. That can't be true because the user has persisted to the database (so the error message doesnt make any sense).
Can anyone see where I'm getting lost?
I tried renaming the User::CompleteRegistration to Users::CompleteRegistrations (and making all references to 'User' become 'Users' in the service class and the registration controller- but I get the same error message in the logs.