undefined method `#{parent_name}=' for singleton associations
Steps to reproduce
The code below produces this error when assigning the parent to the new resource using the :through parameter that points to a method in the controller.
class Member < ApplicationRecord
has_one :subscription, class_name: "Billing::Subscription", inverse_of: :member
end
class Billing::Subscription < ApplicationRecord
belongs_to :member, inverse_of: :subscription
end
class API::V1::Billing::SubscriptionsController < API::APIController
load_and_authorize_resource class: "Billing::Subscription", through: :current_member, singleton: true
def create
@subscription.save!
respond_with(@subscription, location: api_v1_billing_subscription_url)
end
end
Expected behavior
@subscription.member should have been assigned, instead of @subscription.current_member.
There are a few workarounds to this. First, there's the inverse_of parameter on associations, so it's possible to find the reflection and get the proper name. Additionally, when inverse_of is present, you probably don't have to assign the parent manually but rather use build_#{resource_name}.
Another option is to add a new inverse_of option to load_and_authorize_resource method, where we can explicitly specify the parent name.
Actual behavior
undefined method `current_member=' for #<Billing::Subscription id: nil, member_id: nil, price_id: 1, status: "created", ...
System configuration
Rails version: 7.0.3 Ruby version: ruby 3.1.1p18 (2022-02-18 revision 53f5fc4236) [x86_64-darwin20] CanCanCan version: 3.3.0, 3.4.0