Merit#create动作无目标错误,FirstSelection徽章规则配置求助
Hey there! Let's work through that Merit badge error you're hitting when trying to grant the FirstSelection badge to members on their first Selection creation.
First, let's recap your setup to make sure we're aligned:
- Your badge rule lives in
app/models/merit/badge_rules.rb:grant_on 'member/selections#create', badge: 'FirstSelection', to: :member do |selection| selection.member.selections.count == 1 end - Your controller is at
controllers/member/selections_controller.rb - The error you're seeing:
Merit no target found on a #create action
Why This Happens
Merit relies on auto-inferring two key details for badge grants on controller actions:
- The model instance tied to the action (for
#create, it looks for@selectionby default) - The target to grant the badge to (your
:memberhere)
When your controller lives in a namespace (member/), Merit's default inference logic can break—either it can't locate the correct model instance, or it can't resolve the :member target from the action context.
Fixes to Try
1. Explicitly Define Model and Target
Update your badge rule to clarify the model (since the controller is namespaced) and ensure the target is resolved correctly. You have two options here:
- Add
model_nameto explicitly tell Merit which model to use:grant_on 'member/selections#create', badge: 'FirstSelection', to: :member, model_name: 'Selection' do |selection| selection.member.selections.reload.count == 1 end - Or manually specify the target with a proc if Merit can't pick up
:memberautomatically (adjust to match your auth method):grant_on 'member/selections#create', badge: 'FirstSelection', to: proc { |controller| controller.current_member }, model_name: 'Selection' do |selection| selection.member.selections.reload.count == 1 end
2. Verify Your Controller's Instance Variable
Merit looks for an instance variable matching the model name (e.g., @selection for a Selection model) in your #create action. If you're using a different variable name (like @my_selection), add the instance_name option:
grant_on 'member/selections#create', badge: 'FirstSelection', to: :member, model_name: 'Selection', instance_name: :my_selection do |selection| selection.member.selections.reload.count == 1 end
3. Fix Count Logic Timing
When the #create action runs, the new Selection might not be persisted to the database yet—so selection.member.selections.count could return 0 instead of 1. Adding reload ensures you get the latest database count:
selection.member.selections.reload.count == 1
Quick Test
After applying one of these fixes, create a new Selection for a member with no existing entries—your badge should grant without the target error now.
内容的提问来源于stack exchange,提问作者Gregdebrick

