diff --git a/Gemfile.lock b/Gemfile.lock index 8a89b5f..eab5a7b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,6 +3,7 @@ PATH specs: has_friendship (0.1.3) rails (~> 4.0) + stateful_enum GEM remote: https://rubygems.org/ @@ -46,7 +47,7 @@ GEM builder (3.2.2) byebug (8.2.1) coderay (1.1.0) - concurrent-ruby (1.0.0) + concurrent-ruby (1.0.1) coveralls (0.8.10) json (~> 1.8) rest-client (>= 1.6.8, < 2) @@ -91,8 +92,8 @@ GEM loofah (2.0.3) nokogiri (>= 1.5.9) lumberjack (1.0.9) - mail (2.6.3) - mime-types (>= 1.16, < 3) + mail (2.6.4) + mime-types (>= 1.16, < 4) method_source (0.8.2) mime-types (2.99) mini_portile2 (2.0.0) @@ -184,15 +185,16 @@ GEM simplecov-html (~> 0.10.0) simplecov-html (0.10.0) slop (3.6.0) - sprockets (3.5.2) + sprockets (3.6.0) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.0.1) + sprockets-rails (3.0.4) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) sqlite3 (1.3.11) sqlite3 (1.3.11-x64-mingw32) + stateful_enum (0.3.0) term-ansicolor (1.3.2) tins (~> 1.0) thor (0.19.1) @@ -221,6 +223,3 @@ DEPENDENCIES shoulda sqlite3 tzinfo-data - -BUNDLED WITH - 1.11.2 diff --git a/has_friendship.gemspec b/has_friendship.gemspec index a9d3fc3..e4d6fbe 100644 --- a/has_friendship.gemspec +++ b/has_friendship.gemspec @@ -16,6 +16,7 @@ Gem::Specification.new do |s| s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.rdoc"] s.add_dependency "rails", "~> 4.0" + s.add_dependency "stateful_enum" s.add_development_dependency "sqlite3" s.add_development_dependency "rspec-rails" diff --git a/lib/generators/has_friendship/templates/create_friendships.rb b/lib/generators/has_friendship/templates/create_friendships.rb index 37d788f..dd692cb 100644 --- a/lib/generators/has_friendship/templates/create_friendships.rb +++ b/lib/generators/has_friendship/templates/create_friendships.rb @@ -3,7 +3,7 @@ def self.up create_table :friendships do |t| t.references :friendable, polymorphic: true t.integer :friend_id - t.string :status + t.integer :status, index: true t.timestamps end diff --git a/lib/has_friendship/friendable.rb b/lib/has_friendship/friendable.rb index d27bf67..a3e8dca 100644 --- a/lib/has_friendship/friendable.rb +++ b/lib/has_friendship/friendable.rb @@ -11,21 +11,21 @@ def has_friendship class_name: "HasFriendship::Friendship", dependent: :destroy has_many :blocked_friends, - -> { where friendships: { status: 'blocked' } }, + -> { where friendships: { status: 3 } }, through: :friendships, source: :friend has_many :friends, - -> { where friendships: { status: 'accepted' } }, + -> { where friendships: { status: 2 } }, through: :friendships has_many :requested_friends, - -> { where friendships: { status: 'requested' } }, + -> { where friendships: { status: 1 } }, through: :friendships, source: :friend has_many :pending_friends, - -> { where friendships: { status: 'pending' } }, + -> { where friendships: { status: 0 } }, through: :friendships, source: :friend @@ -43,16 +43,15 @@ module InstanceMethods def friend_request(friend) unless self == friend || HasFriendship::Friendship.exist?(self, friend) transaction do - HasFriendship::Friendship.create_relation(self, friend, status: 'pending') - HasFriendship::Friendship.create_relation(friend, self, status: 'requested') + HasFriendship::Friendship.create_relation(self, friend, status: 0) + HasFriendship::Friendship.create_relation(friend, self, status: 1) end end end def accept_request(friend) on_relation_with(friend) do |one, other| - HasFriendship::Friendship.find_unblocked_friendship(one, other) - .update(status: 'accepted') + HasFriendship::Friendship.find_unblocked_friendship(one, other).accept! end end @@ -66,8 +65,7 @@ def decline_request(friend) def block_friend(friend) on_relation_with(friend) do |one, other| - HasFriendship::Friendship.find_unblocked_friendship(one, other) - .update(status: 'blocked', blocker_id: self.id) + HasFriendship::Friendship.find_unblocked_friendship(one, other).block! end end @@ -86,7 +84,7 @@ def on_relation_with(friend) end def friends_with?(friend) - HasFriendship::Friendship.find_relation(self, friend, status: 'accepted').any? + HasFriendship::Friendship.find_relation(self, friend, status: 2).any? end private diff --git a/lib/has_friendship/friendship.rb b/lib/has_friendship/friendship.rb index 676def8..b45874f 100644 --- a/lib/has_friendship/friendship.rb +++ b/lib/has_friendship/friendship.rb @@ -1,5 +1,20 @@ module HasFriendship class Friendship < ActiveRecord::Base + + enum status: { pending: 0, requested: 1, accepted: 2, blocked: 3 } do + event :accept do + transition [:pending, :requested] => :accepted + end + + event :block do + before do + self.blocker_id = self.friendable.id + end + + transition all - [:blocked] => :blocked + end + end + def self.relation_attributes(one, other, status: nil) attr = { friendable_id: one.id, @@ -29,11 +44,11 @@ def self.exist?(friendable, friend) end def self.find_unblocked_friendship(friendable, friend) - find_relation(friendable, friend).where.not(status: "blocked").first + find_relation(friendable, friend).where.not(status: 3).first end def self.find_blocked_friendship(friendable, friend) - find_relation(friendable, friend).where(status: "blocked").first + find_relation(friendable, friend).where(status: 3).first end def self.find_one_side(one, other) diff --git a/spec/internal/db/schema.rb b/spec/internal/db/schema.rb index 79f55a6..e3d598a 100644 --- a/spec/internal/db/schema.rb +++ b/spec/internal/db/schema.rb @@ -17,7 +17,7 @@ t.integer "friendable_id" t.string "friendable_type" t.integer "friend_id" - t.string "status" + t.integer "status", index: true t.integer "blocker_id" t.datetime "created_at" t.datetime "updated_at" diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index e11544d..52f9eb4 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -7,6 +7,7 @@ require 'shoulda' require 'support/friendship_macro' +require 'stateful_enum' load 'internal/db/schema.rb'