TAGS ARE SO COOL
This commit is contained in:
parent
10345b14a8
commit
c1bcfef90c
6 changed files with 118 additions and 6 deletions
6
Gemfile
6
Gemfile
|
|
@ -24,12 +24,12 @@ gem 'twitter', :git => 'git://github.com/jnunemaker/twitter.git', :ref => 'ef122
|
||||||
gem 'haml', '3.0.25'
|
gem 'haml', '3.0.25'
|
||||||
gem 'will_paginate', '3.0.pre2'
|
gem 'will_paginate', '3.0.pre2'
|
||||||
|
|
||||||
#Statistics
|
|
||||||
gem 'googlecharts'
|
|
||||||
|
|
||||||
#Inflected translations
|
#Inflected translations
|
||||||
gem 'i18n-inflector-rails', '~> 1.0'
|
gem 'i18n-inflector-rails', '~> 1.0'
|
||||||
|
|
||||||
|
#Tags
|
||||||
|
gem 'acts-as-taggable-on', '2.0.6'
|
||||||
|
|
||||||
#Uncatagorized
|
#Uncatagorized
|
||||||
gem 'roxml', :git => 'git://github.com/Empact/roxml.git', :ref => '7ea9a9ffd2338aaef5b0'
|
gem 'roxml', :git => 'git://github.com/Empact/roxml.git', :ref => '7ea9a9ffd2338aaef5b0'
|
||||||
gem 'addressable', '2.2.2', :require => 'addressable/uri'
|
gem 'addressable', '2.2.2', :require => 'addressable/uri'
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ GEM
|
||||||
activemodel (= 3.0.3)
|
activemodel (= 3.0.3)
|
||||||
activesupport (= 3.0.3)
|
activesupport (= 3.0.3)
|
||||||
activesupport (3.0.3)
|
activesupport (3.0.3)
|
||||||
|
acts-as-taggable-on (2.0.6)
|
||||||
addressable (2.2.2)
|
addressable (2.2.2)
|
||||||
arel (2.0.9)
|
arel (2.0.9)
|
||||||
aws (2.3.32)
|
aws (2.3.32)
|
||||||
|
|
@ -189,7 +190,6 @@ GEM
|
||||||
gem_plugin (0.2.3)
|
gem_plugin (0.2.3)
|
||||||
gherkin (2.3.3)
|
gherkin (2.3.3)
|
||||||
json (~> 1.4.6)
|
json (~> 1.4.6)
|
||||||
googlecharts (1.6.1)
|
|
||||||
haml (3.0.25)
|
haml (3.0.25)
|
||||||
hashie (0.4.0)
|
hashie (0.4.0)
|
||||||
highline (1.6.1)
|
highline (1.6.1)
|
||||||
|
|
@ -387,6 +387,7 @@ PLATFORMS
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
SystemTimer (= 1.2.1)
|
SystemTimer (= 1.2.1)
|
||||||
|
acts-as-taggable-on (= 2.0.6)
|
||||||
addressable (= 2.2.2)
|
addressable (= 2.2.2)
|
||||||
aws (= 2.3.32)
|
aws (= 2.3.32)
|
||||||
bundler (>= 1.0.0)
|
bundler (>= 1.0.0)
|
||||||
|
|
@ -408,7 +409,6 @@ DEPENDENCIES
|
||||||
fog (= 0.3.25)
|
fog (= 0.3.25)
|
||||||
foreigner (= 0.9.1)
|
foreigner (= 0.9.1)
|
||||||
fuubar
|
fuubar
|
||||||
googlecharts
|
|
||||||
haml (= 3.0.25)
|
haml (= 3.0.25)
|
||||||
http_accept_language!
|
http_accept_language!
|
||||||
i18n-inflector-rails (~> 1.0)
|
i18n-inflector-rails (~> 1.0)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ class StatusMessage < Post
|
||||||
require File.join(Rails.root, 'lib/youtube_titles')
|
require File.join(Rails.root, 'lib/youtube_titles')
|
||||||
include ActionView::Helpers::TextHelper
|
include ActionView::Helpers::TextHelper
|
||||||
|
|
||||||
|
acts_as_taggable
|
||||||
|
acts_as_taggable_on :tags
|
||||||
|
|
||||||
validates_length_of :message, :maximum => 1000, :message => "please make your status messages less than 1000 characters"
|
validates_length_of :message, :maximum => 1000, :message => "please make your status messages less than 1000 characters"
|
||||||
xml_name :status_message
|
xml_name :status_message
|
||||||
xml_attr :raw_message
|
xml_attr :raw_message
|
||||||
|
|
@ -22,6 +25,8 @@ class StatusMessage < Post
|
||||||
get_youtube_title message
|
get_youtube_title message
|
||||||
end
|
end
|
||||||
|
|
||||||
|
before_create :build_tags
|
||||||
|
|
||||||
def message(opts = {})
|
def message(opts = {})
|
||||||
self.formatted_message(opts)
|
self.formatted_message(opts)
|
||||||
end
|
end
|
||||||
|
|
@ -84,6 +89,22 @@ class StatusMessage < Post
|
||||||
identifiers.empty? ? [] : Person.where(:diaspora_handle => identifiers)
|
identifiers.empty? ? [] : Person.where(:diaspora_handle => identifiers)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def build_tags
|
||||||
|
self.tag_list = tag_strings
|
||||||
|
end
|
||||||
|
|
||||||
|
def tag_strings
|
||||||
|
regex = /(^|\s)#(\w+)/
|
||||||
|
matches = self.raw_message.scan(regex).map do |match|
|
||||||
|
match.last
|
||||||
|
end
|
||||||
|
unique_matches = matches.inject(Hash.new) do |h,element|
|
||||||
|
h[element.downcase] = element unless h[element.downcase]
|
||||||
|
h
|
||||||
|
end
|
||||||
|
unique_matches.values
|
||||||
|
end
|
||||||
|
|
||||||
def to_activity
|
def to_activity
|
||||||
<<-XML
|
<<-XML
|
||||||
<entry>
|
<entry>
|
||||||
|
|
|
||||||
28
db/migrate/20110311000150_acts_as_taggable_on_migration.rb
Normal file
28
db/migrate/20110311000150_acts_as_taggable_on_migration.rb
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
class ActsAsTaggableOnMigration < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :tags do |t|
|
||||||
|
t.string :name
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table :taggings do |t|
|
||||||
|
t.references :tag
|
||||||
|
|
||||||
|
# You should make sure that the column created is
|
||||||
|
# long enough to store the required class names.
|
||||||
|
t.references :taggable, :polymorphic => {:limit => 127}
|
||||||
|
t.references :tagger, :polymorphic => {:limit => 127}
|
||||||
|
|
||||||
|
t.string :context, :limit => 127
|
||||||
|
|
||||||
|
t.datetime :created_at
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index :taggings, :tag_id
|
||||||
|
add_index :taggings, [:taggable_id, :taggable_type, :context]
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :taggings
|
||||||
|
drop_table :tags
|
||||||
|
end
|
||||||
|
end
|
||||||
19
db/schema.rb
19
db/schema.rb
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20110301202619) do
|
ActiveRecord::Schema.define(:version => 20110311000150) do
|
||||||
|
|
||||||
create_table "aspect_memberships", :force => true do |t|
|
create_table "aspect_memberships", :force => true do |t|
|
||||||
t.integer "aspect_id", :null => false
|
t.integer "aspect_id", :null => false
|
||||||
|
|
@ -459,6 +459,23 @@ ActiveRecord::Schema.define(:version => 20110301202619) do
|
||||||
add_index "services", ["mongo_id"], :name => "index_services_on_mongo_id"
|
add_index "services", ["mongo_id"], :name => "index_services_on_mongo_id"
|
||||||
add_index "services", ["user_id"], :name => "index_services_on_user_id"
|
add_index "services", ["user_id"], :name => "index_services_on_user_id"
|
||||||
|
|
||||||
|
create_table "taggings", :force => true do |t|
|
||||||
|
t.integer "tag_id"
|
||||||
|
t.integer "taggable_id"
|
||||||
|
t.string "taggable_type", :limit => 127
|
||||||
|
t.integer "tagger_id"
|
||||||
|
t.string "tagger_type", :limit => 127
|
||||||
|
t.string "context", :limit => 127
|
||||||
|
t.datetime "created_at"
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
|
||||||
|
add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context"
|
||||||
|
|
||||||
|
create_table "tags", :force => true do |t|
|
||||||
|
t.string "name"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "users", :force => true do |t|
|
create_table "users", :force => true do |t|
|
||||||
t.string "username"
|
t.string "username"
|
||||||
t.text "serialized_private_key"
|
t.text "serialized_private_key"
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,11 @@ describe StatusMessage do
|
||||||
status.should_receive(:create_mentions)
|
status.should_receive(:create_mentions)
|
||||||
status.save
|
status.save
|
||||||
end
|
end
|
||||||
|
it 'calls build_tags' do
|
||||||
|
status = Factory.build(:status_message)
|
||||||
|
status.should_receive(:build_tags)
|
||||||
|
status.save
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#diaspora_handle=' do
|
describe '#diaspora_handle=' do
|
||||||
|
|
@ -103,6 +108,9 @@ STR
|
||||||
it 'escapes the link title' do
|
it 'escapes the link title' do
|
||||||
p = @people[0].profile
|
p = @people[0].profile
|
||||||
p.first_name="</a><script>alert('h')</script>"
|
p.first_name="</a><script>alert('h')</script>"
|
||||||
|
["a", "b", "A", "C"]\
|
||||||
|
.inject(Hash.new){ |h,element| h[element.downcase] = element unless h[element.downcase] ; h }\
|
||||||
|
.values
|
||||||
p.save!
|
p.save!
|
||||||
|
|
||||||
@sm.formatted_message.should_not include(@people[0].profile.first_name)
|
@sm.formatted_message.should_not include(@people[0].profile.first_name)
|
||||||
|
|
@ -165,6 +173,44 @@ STR
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
describe 'tags' do
|
||||||
|
before do
|
||||||
|
@sm = Factory.build(:status_message)
|
||||||
|
end
|
||||||
|
describe '#build_tags' do
|
||||||
|
it 'builds the tags' do
|
||||||
|
@sm.message = '#what'
|
||||||
|
@sm.build_tags
|
||||||
|
@sm.tag_list.should == ['what']
|
||||||
|
lambda {
|
||||||
|
@sm.save
|
||||||
|
}.should change{@sm.tags.count}.by(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
describe '#tag_strings' do
|
||||||
|
it 'returns a string for every #thing' do
|
||||||
|
str = '#what #hey #that"smybike. #@hey ##boo # #THATWASMYBIKE #hey#there #135440we #abc/23 ###'
|
||||||
|
arr = ['what', 'hey', 'that', 'THATWASMYBIKE', '135440we', 'abc']
|
||||||
|
|
||||||
|
@sm.message = str
|
||||||
|
@sm.tag_strings.should =~ arr
|
||||||
|
end
|
||||||
|
it 'returns no duplicates' do
|
||||||
|
str = '#what #what #what #whaaaaaaaaaat'
|
||||||
|
arr = ['what','whaaaaaaaaaat']
|
||||||
|
|
||||||
|
@sm.message = str
|
||||||
|
@sm.tag_strings.should =~ arr
|
||||||
|
end
|
||||||
|
it 'is case insensitive' do
|
||||||
|
str = '#what #wHaT #WHAT'
|
||||||
|
arr = ['what']
|
||||||
|
|
||||||
|
@sm.message = str
|
||||||
|
@sm.tag_strings.should =~ arr
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
describe "XML" do
|
describe "XML" do
|
||||||
before do
|
before do
|
||||||
@message = Factory.create(:status_message, :message => "I hate WALRUSES!", :author => @user.person)
|
@message = Factory.create(:status_message, :message => "I hate WALRUSES!", :author => @user.person)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue