Reputation: 15
I recently updated my knowledgebase app to have a pretty standard has_many through association. Previously articles belonged to a category and a category had many articles. Now it is situated as the following:
class Article < ApplicationRecord
has_many :categorizations
has_many :categories, :through => :categorizations
class Category < ApplicationRecord
has_many :categorizations
has_many :articles, :through => :categorizations, dependent: :destroy
class Categorization < ApplicationRecord
belongs_to :article
belongs_to :category
One of the categories I have is the "Internal" category. What I am trying to accomplish is a helper method that I can us to perform actions if a particular article has the Internal category set on it. Something like the following:
if @article.internal?
do stuff
end
I am thinking it need to be in the articles_helper.rb file.
module ArticlesHelper
def internal?
figure out if @article has category "internal"
end
end
I have the following but am thinking I am on the wrong track and could use some help:
def internal?
@internal_cat = []
@article.categories.each do |n|
if (n.name == "Internal")
@internal_cat = n.name
end
end
end
Any help would be greatly appreciated!
Upvotes: 0
Views: 111
Reputation: 102443
This is the wrong use case for a helper method. Helper methods are used to simplify and DRY your views, and occasionally controllers. For example the form helpers make it easier to create forms and bind models to inputs.
Helpers are modules that are mixed into the view context.
What you want here is just a plain old method on your model as it can act on self
:
class Article < ApplicationRecord
# ...
def has_category?(name)
categories.exists?(name: name)
end
def internal?
has_category?("Internal")
end
end
Later you can refactor this code into a module if needed but this is not the same thing as a helper. Rather its parallel inheritance through the mixin pattern.
module Categorized
extend ActiveSupport::Concern
included do
has_many :categorizations, as: :resource
has_many :categories, through: :categorizations
end
def has_category?(name)
categories.exists?(name: name)
end
end
class Article < ApplicationRecord
include Categorized
end
class Video < ApplicationRecord
include Categorized
end
You also want to set the dependent: :destroy
option on the categorizations
join table. The way you have set it up destroying an article will destroy the normalized row in categories!
class Article < ApplicationRecord
has_many :categorizations, dependent: :destroy
has_many :categories, through: :categorizations
class Category < ApplicationRecord
has_many :categorizations, dependent: :destroy
has_many :articles, through: :categorizations
Upvotes: 1