Permalink
Browse files

up to 11.2

  • Loading branch information...
1 parent c92f877 commit 28e330c540c91ef6e662d0ed09891bfb207953a3 @ajb committed May 23, 2012
@@ -0,0 +1,9 @@
+class Relationship < ActiveRecord::Base
+ attr_accessible :followed_id
+
+ belongs_to :follower, class_name: "User"
+ belongs_to :followed, class_name: "User"
+
+ validates :follower_id, presence: true
+ validates :followed_id, presence: true
+end
@@ -12,7 +12,15 @@
class User < ActiveRecord::Base
attr_accessible :name, :email, :password, :password_confirmation
has_secure_password
- has_many :microposts, dependent: :destroy
+ has_many :microposts, dependent: :destroy
+ has_many :relationships, foreign_key: "follower_id", dependent: :destroy
+ has_many :followed_users, through: :relationships, source: :followed
+
+ has_many :reverse_relationships, foreign_key: "followed_id",
+ class_name: "Relationship",
+ dependent: :destroy
+
+ has_many :followers, through: :reverse_relationships, source: :follower
before_save { |user| user.email = email.downcase }
before_save :create_remember_token
@@ -21,6 +29,18 @@ def feed
Micropost.where('user_id = ?', id)
end
+ def following?(other_user)
+ relationships.find_by_followed_id(other_user.id)
+ end
+
+ def follow!(other_user)
+ relationships.create!(followed_id: other_user.id)
+ end
+
+ def unfollow!(other_user)
+ relationships.find_by_followed_id(other_user.id).destroy
+ end
+
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :name, presence: true, length: { maximum: 50 }
@@ -0,0 +1,14 @@
+class CreateRelationships < ActiveRecord::Migration
+ def change
+ create_table :relationships do |t|
+ t.integer :follower_id
+ t.integer :followed_id
+
+ t.timestamps
+ end
+
+ add_index :relationships, :follower_id
+ add_index :relationships, :followed_id
+ add_index :relationships, [:follower_id, :followed_id], unique: true
+ end
+end
View
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120521231729) do
+ActiveRecord::Schema.define(:version => 20120523175525) do
create_table "microposts", :force => true do |t|
t.string "content"
@@ -22,6 +22,17 @@
add_index "microposts", ["user_id", "created_at"], :name => "index_microposts_on_user_id_and_created_at"
+ create_table "relationships", :force => true do |t|
+ t.integer "follower_id"
+ t.integer "followed_id"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
+ add_index "relationships", ["followed_id"], :name => "index_relationships_on_followed_id"
+ add_index "relationships", ["follower_id", "followed_id"], :name => "index_relationships_on_follower_id_and_followed_id", :unique => true
+ add_index "relationships", ["follower_id"], :name => "index_relationships_on_follower_id"
+
create_table "users", :force => true do |t|
t.string "name"
t.string "email"
@@ -0,0 +1,34 @@
+require 'spec_helper'
+
+describe Relationship do
+
+ let(:follower) { FactoryGirl.create(:user) }
+ let(:followed) { FactoryGirl.create(:user) }
+ let(:relationship) { follower.relationships.build(followed_id: followed.id) }
+
+ subject { relationship }
+
+ it { should be_valid }
+
+ describe "accessible attributes" do
+ it { should_not be_accessible(:follower_id) }
+ end
+
+ describe "follower methods" do
+ it { should respond_to(:follower) }
+ it { should respond_to(:followed) }
+ its(:follower) { should == follower }
+ its(:followed) { should == followed }
+ end
+
+ describe "when follower_id is not present" do
+ before { relationship.follower_id = nil }
+ it { should_not be_valid }
+ end
+
+ describe "when followed_id is not present" do
+ before { relationship.followed_id = nil }
+ it { should_not be_valid }
+ end
+
+end
@@ -29,10 +29,41 @@
it { should respond_to(:authenticate) }
it { should respond_to(:admin) }
it { should respond_to(:microposts) }
+ it { should respond_to(:feed) }
+ it { should respond_to(:relationships) }
+ it { should respond_to(:followed_users) }
+ it { should respond_to(:reverse_relationships) }
+ it { should respond_to(:followers) }
+ it { should respond_to(:following?) }
+ it { should respond_to(:follow!) }
+ it { should respond_to(:unfollow!) }
it { should be_valid }
it { should_not be_admin }
+ describe "following" do
+ let(:other_user) { FactoryGirl.create(:user) }
+ before do
+ @user.save
+ @user.follow!(other_user)
+ end
+
+ it { should be_following(other_user) }
+ its(:followed_users) { should include(other_user) }
+
+ describe "and unfollowing" do
+ before { @user.unfollow!(other_user) }
+
+ it { should_not be_following(other_user) }
+ its(:followed_users) { should_not include(other_user) }
+ end
+
+ describe "followed user" do
+ subject { other_user }
+ its(:followers) { should include(@user) }
+ end
+ end
+
describe "with admin set to true" do
before { @user.toggle!(:admin) }
it { should be_admin }

0 comments on commit 28e330c

Please sign in to comment.