Rails 4: Helper method not retrieving associated records

62 views Asked by At

I have a custom helper method who's sole purpose is to count data of associated records which will be displayed in the view. In the rails console I can add Campaign.find(1).plan.subscribers and retrieve the list of subscribers yet, I can't do that in my custom Helper Method.

Here's the helper method.. (Note: You can see where I tried printing out campaign.plan.subscribers to see if it was registering before the loop...it's not)

helpers/application_helper.rb

module ApplicationHelper

    def current_recipients(campaign)
        @target_program = campaign.program.name
        @recipients = 0

        #p campaign.plan.subscribers

        campaign.plan.subscribers.each do |s|
            case @target_program
                when "Caspian Star" && s.star?
                    @recipients += 1
                when "STIX" && s.stix?
                    @recipients += 1
                when "PPCI" && s.ppci?
                    @recipients += 1
                else
                    @recipients += 0
                end
        end
        @recipients
    end
end

My spec..

spec/helpers.application_helper_spec.rb

require "rails_helper"

RSpec.describe ApplicationHelper, :type => :helper do

    describe "Counting campaign recipients" do
        subject(:campaign) { create(:campaign, plan: plan, program: program) }
        let(:program) { create(:program) }
        let(:plan) { create(:plan) }

        it "finds subscribers under campaign plan and program" do
            expect(helper.current_recipients(campaign)).to eq 3
        end
    end
end

Failure

  1) ApplicationHelper Counting campaign recipients finds subscribers under campaign plan and program
     Failure/Error: expect(helper.current_recipients(campaign)).to eq 3

       expected: 3
            got: 0

       (compared using ==)

The relationships..

app/models/..

Class Campaign < ActiveRecord::Base
    belongs_to :program
    belongs_to :plan
end

Class Plan < ActiveRecord::Base
    has_many :campaigns
    has_many :subscribers, through: :plannables
    has_many :plannables
end

Class Program < ActiveRecord::Base
    has_many :campaigns
end

class Subscriber < ActiveRecord::Base
    has_many :plans, through: :plannables
    has_many :plannables
end

class Plannable < ActiveRecord::Base
    belongs_to :plan
    belongs_to :provider
end

EDIT

Here's the add factories as requested.

FactoryGirl.define do

    factory :campaign do |x|
        x.sequence(:name) { |y| "Q6 201#{y}" }
        x.sequence(:comment) { |y| "JIRA OI-6#{y}" }
        channels ["Folder", "Fax"]
    end

    factory :program do
        name "Caspian Star"
    end

    factory :plan do
        name "Third Storm Connect"
    end
end
1

There are 1 answers

0
shroy On BEST ANSWER

The issue ended up being in the case statement which wasn't throwing any obvious errors. It didn't respond well to the && on the when conditions, so I placed them underneath and it seems to work fine now. Here is what the code looks like now..

module ApplicationHelper

    def current_recipients(campaign)
        @target_program = campaign.program.name
        @recipients = 0

        campaign.plan.subscribers.each do |s|
            case @target_program
                when "Caspian Star"
                    s.star?
                    @recipients += 1
                when "STIX"
                    s.stix?
                    @recipients += 1
                when "PPCI"
                    s.ppci?
                    @recipients += 1
                else
                    @recipients += 0
                end
        end
        @recipients
    end
end

With a suggestion made by @steveklein during a chat session, I was able to get my test to pass by linking my objects associations together in this manner..

describe "Counting campaign recipients" do
    it "finds subscribers under chosen campaign plan and program" do
        campaign = create(:campaign)
        plan = create(:plan)
        campaign.plan = plan
        campaign.program = create(:program)

    3.times do
        subscriber = create(:subscriber, star: true)
        subscriber.plans << plan
    end

        expect(helper.current_recipients(campaign)).to eq 3
    end
end