From d42c6969f7235f55e5da55d04385a9ce237ef218 Mon Sep 17 00:00:00 2001 From: Justin Aiken <60tonangel@gmail.com> Date: Tue, 1 Jul 2014 15:30:19 -0600 Subject: [PATCH] Add option to only generate hashtags if a specific condition is met --- README.md | 24 +++++++++++++++ lib/simple_hashtag/hashtaggable.rb | 21 +++++++++++++ spec/simple_hashtag_spec.rb | 49 ++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/README.md b/README.md index 445fb90..8331afe 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,30 @@ class Picture < ActiveRecord::Base end ``` +If you only want hashtags created based on conditions, +you can create a guard with `hashtag_if`: + +```ruby +class Post < ActiveRecord::Base + include SimpleHashtag::Hashtaggable + + hashtag_if ->(post) { post.body =~ /ruby/ } +end + +# or... + +class Post < ActiveRecord::Base + include SimpleHashtag::Hashtaggable + + hashtag_if :about_ruby? + + def about_ruby? + body =~ /ruby/ + end +end +``` + + From here on, if your text contains a hashtag, say _#RubyRocks_, _Simple Hasthag_ will find it, store it in a table and retreive it and its associated object if asked. Helpers are also available to create a link when displaying the text. diff --git a/lib/simple_hashtag/hashtaggable.rb b/lib/simple_hashtag/hashtaggable.rb index 533f7e7..c24fede 100644 --- a/lib/simple_hashtag/hashtaggable.rb +++ b/lib/simple_hashtag/hashtaggable.rb @@ -2,6 +2,8 @@ module SimpleHashtag module Hashtaggable extend ActiveSupport::Concern + class InvalidHashtagGuard < ArgumentError; end + included do has_many :hashtaggings, as: :hashtaggable, class_name: "SimpleHashtag::Hashtagging", dependent: :destroy has_many :hashtags, through: :hashtaggings, class_name: "SimpleHashtag::Hashtag" @@ -15,9 +17,23 @@ def hashtaggable_content end def update_hashtags + if hashtag_guard.present? + if hashtag_guard.respond_to?(:call) + return unless hashtag_guard.call self + elsif self.respond_to? hashtag_guard + return unless self.send hashtag_guard + else + raise InvalidHashtagGuard + end + end + self.hashtags = parsed_hashtags end + def hashtag_guard + self.class.hashtag_guard + end + def parsed_hashtags parsed_hashtags = [] array_of_hashtags_as_string = scan_for_hashtags(hashtaggable_content) @@ -36,10 +52,15 @@ def scan_for_hashtags(content) module ClassMethods attr_accessor :hashtaggable_attribute_name + attr_accessor :hashtag_guard def hashtaggable_attribute(name=nil) self.hashtaggable_attribute_name ||= name || :body end + + def hashtag_if(guard) + self.hashtag_guard = guard + end end end end diff --git a/spec/simple_hashtag_spec.rb b/spec/simple_hashtag_spec.rb index 33af90a..bb87143 100644 --- a/spec/simple_hashtag_spec.rb +++ b/spec/simple_hashtag_spec.rb @@ -134,5 +134,54 @@ h.name.should eq "chance" h.hashtaggables.count.should eq 2 end + + context "with a lamdba guard" do + class GuardedPost < Post + hashtag_if lambda { |post| post.body =~ /Community/ } + end + + it "creates hashtags if the guard is fulfilled" do + GuardedPost.create(body: 'Community saved! #sixseasonsandamovie') + p = Post.last + p.hashtags.first.name.should eq 'sixseasonsandamovie' + end + + it "does not create hashtags if the guard is notfulfilled" do + GuardedPost.create(body: 'To boldly go... #startrek') + p = Post.last + p.hashtags.should == [] + end + end + + context "with a method guard" do + class MethodGuardedPost < Post + hashtag_if :is_community? + + def is_community? + body =~ /Community/ + end + end + + it "creates hashtags if the guard is fulfilled" do + MethodGuardedPost.create(body: 'Community saved! #sixseasonsandamovie') + Post.last.hashtags.first.name.should eq 'sixseasonsandamovie' + end + + it "does not create hashtags if the guard is notfulfilled" do + MethodGuardedPost.create(body: 'To boldly go... #startrek') + Post.last.hashtags.should == [] + end + end + + context "with an invalid guard" do + class PoorlyGuardedPost < Post + hashtag_if :this_isnt_even_real + end + end + + it "raises an error" do + p = PoorlyGuardedPost.new(body: '#doesntmatter #thisisgoingtofail') + expect{ p.save! }.to raise_error SimpleHashtag::Hashtaggable::InvalidHashtagGuard + end end end