From 7b3a2b07ee164f4928fcf7cdba1fe35227b077f5 Mon Sep 17 00:00:00 2001 From: Raphael Sofaer <raphael@joindiaspora.com> Date: Wed, 9 Feb 2011 14:12:21 -0800 Subject: [PATCH] Removed n-query, created mentions table --- app/models/mention.rb | 10 ++++++ app/models/post.rb | 3 +- app/models/status_message.rb | 19 +++++++++-- db/migrate/20110209204702_create_mentions.rb | 15 +++++++++ db/schema.rb | 11 ++++++- spec/models/status_message_spec.rb | 33 +++++++++++++++++--- 6 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 app/models/mention.rb create mode 100644 db/migrate/20110209204702_create_mentions.rb diff --git a/app/models/mention.rb b/app/models/mention.rb new file mode 100644 index 0000000000..deb065b675 --- /dev/null +++ b/app/models/mention.rb @@ -0,0 +1,10 @@ +# Copyright (c) 2010, Diaspora Inc. This file is +# licensed under the Affero General Public License version 3 or later. See +# the COPYRIGHT file. + +class Mention < ActiveRecord::Base + belongs_to :post + belongs_to :person + validates_presence_of :post + validates_presence_of :person +end diff --git a/app/models/post.rb b/app/models/post.rb index df28343702..98671c505c 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -17,6 +17,7 @@ class Post < ActiveRecord::Base has_many :comments, :order => 'created_at ASC', :dependent => :destroy has_many :post_visibilities has_many :aspects, :through => :post_visibilities + has_many :mentions, :dependent => :delete_all belongs_to :person cattr_reader :per_page @@ -81,7 +82,7 @@ class Post < ActiveRecord::Base else user.add_post_to_aspects(local_post) Rails.logger.info("event=receive payload_type=#{self.class} update=true status=complete sender=#{self.diaspora_handle} existing_post=#{local_post.id}") - return local_post + return local_post end elsif !local_post self.save diff --git a/app/models/status_message.rb b/app/models/status_message.rb index 9ee3c0e8c5..dc500e0f97 100644 --- a/app/models/status_message.rb +++ b/app/models/status_message.rb @@ -43,17 +43,32 @@ class StatusMessage < Post person = people.detect{ |p| p.diaspora_handle == inner_captures.last } - person ? "<a href=\"/people/#{person.id}\">#{ERB::Util.h(person.name)}</a>" : inner_captures.first + person ? "<a href=\"/people/#{person.id}\" class=\"mention\">#{ERB::Util.h(person.name)}</a>" : ERB::Util.h(inner_captures.first) end form_message end def mentioned_people + if self.persisted? + create_mentions if self.mentions.empty? + self.mentions.includes(:person => :profile).map{ |mention| mention.person } + else + mentioned_people_from_string + end + end + + def create_mentions + mentioned_people_from_string.each do |person| + self.mentions.create(:person => person) + end + end + + def mentioned_people_from_string regex = /@\{([^;]+); ([^\}]+)\}/ identifiers = self.raw_message.scan(regex).map do |match| match.last end - Person.where(:diaspora_handle => identifiers) + identifiers.empty? ? [] : Person.where(:diaspora_handle => identifiers) end def to_activity diff --git a/db/migrate/20110209204702_create_mentions.rb b/db/migrate/20110209204702_create_mentions.rb new file mode 100644 index 0000000000..d4bbbf39e8 --- /dev/null +++ b/db/migrate/20110209204702_create_mentions.rb @@ -0,0 +1,15 @@ +class CreateMentions < ActiveRecord::Migration + def self.up + create_table :mentions do |t| + t.integer :post_id, :null => false + t.integer :person_id, :null => false + end + add_index :mentions, :post_id + add_index :mentions, :person_id + add_index :mentions, [:person_id, :post_id], :unique => true + end + + def self.down + drop_table :mentions + end +end diff --git a/db/schema.rb b/db/schema.rb index c4fbefa114..3c0a97c169 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20110202015222) do +ActiveRecord::Schema.define(:version => 20110209204702) do create_table "aspect_memberships", :force => true do |t| t.integer "aspect_id", :null => false @@ -95,6 +95,15 @@ ActiveRecord::Schema.define(:version => 20110202015222) do add_index "invitations", ["recipient_id"], :name => "index_invitations_on_recipient_id" add_index "invitations", ["sender_id"], :name => "index_invitations_on_sender_id" + create_table "mentions", :force => true do |t| + t.integer "post_id", :null => false + t.integer "person_id", :null => false + end + + add_index "mentions", ["person_id", "post_id"], :name => "index_mentions_on_person_id_and_post_id", :unique => true + add_index "mentions", ["person_id"], :name => "index_mentions_on_person_id" + add_index "mentions", ["post_id"], :name => "index_mentions_on_post_id" + create_table "mongo_aspect_memberships", :force => true do |t| t.string "aspect_mongo_id" t.string "contact_mongo_id" diff --git a/spec/models/status_message_spec.rb b/spec/models/status_message_spec.rb index acf4551769..320b650863 100644 --- a/spec/models/status_message_spec.rb +++ b/spec/models/status_message_spec.rb @@ -73,8 +73,8 @@ STR describe '#formatted_message' do it 'adds the links in the formated message text' do @sm.formatted_message.should == <<-STR -#{link_to(@people[0].name, person_path(@people[0]))} can mention people like Raphael #{link_to(@people[1].name, person_path(@people[1]))} -can mention people like Raphaellike Raphael #{link_to(@people[2].name, person_path(@people[2]))} can mention people like Raph +#{link_to(@people[0].name, person_path(@people[0]), :class => 'mention')} can mention people like Raphael #{link_to(@people[1].name, person_path(@people[1]), :class => 'mention')} +can mention people like Raphaellike Raphael #{link_to(@people[2].name, person_path(@people[2]), :class => 'mention')} can mention people like Raph STR end it 'leaves the name of people that cannot be found' do @@ -102,8 +102,33 @@ STR end end - it 'extracts the mentioned people from the message' do - @sm.mentioned_people.to_set.should == @people.to_set + describe '#mentioned_people_from_string' do + it 'extracts the mentioned people from the message' do + @sm.mentioned_people_from_string.to_set.should == @people.to_set + end + end + describe '#create_mentions' do + it 'creates a mention for everyone mentioned in the message' do + @sm.should_receive(:mentioned_people_from_string).and_return(@people) + @sm.mentions.delete_all + @sm.create_mentions + @sm.mentions(true).map{|m| m.person}.to_set.should == @people.to_set + end + end + describe '#mentioned_people' do + it 'calls create_mentions if there are no mentions in the db' do + @sm.mentions.delete_all + @sm.should_receive(:create_mentions) + @sm.mentioned_people + end + it 'returns the mentioned people' do + @sm.mentions.delete_all + @sm.mentioned_people.to_set.should == @people.to_set + end + it 'does not call create_mentions if there are mentions in the db' do + @sm.should_not_receive(:create_mentions) + @sm.mentioned_people + end end end describe "XML" do -- GitLab