为Oracle和Ruby on Rails添加标签(二)

日期: 2007-12-04 作者:Matt Kern 来源:TechTarget中国

  好了,继续为 Discographr 的其他模型添加标签。因为希望能为已定义的所有模型添加标签,所以您需要为 Album 和 Song 模型添加 sacts_as_taggable 调用:  

class Album < ActiveRecord::Base
  belongs_to :artist
  acts_as_taggable
  end
  class Song < ActiveRecord::Base
  belongs_to :album
  acts_as_taggable
  end

  现在您的所有模型都可添加标签了,那就可开始在应用程序中使用标签信息吧。鉴于现在您仍未编写任何控制器,可以使用方便的 script/console 来测试可添加标签的新模型。要启动控制台,执行:

  $ script/console

  创建一个艺术家、唱片和歌曲:  

>> a = Artist.new( :name => "Bob Dylan" )
  => #nil, "name"=>"Bob Dylan", "updated_on"=>nil}>
  >> a.save
  => true
  >> alb = Album.new( :release_name => "Good As I Been To You",
  ?> :artist => a,
  ?> :year => 1992 )
  => #nil, "artist_id"=>10001,
  "updated_on"=>nil, "year"=>1992, "release_name"=>"Good As I Been To You"}, @artist=#<
  Artist:0x35589dc @new_record=false, @new_record_before_save=true, @attributes={"created_on"=>Sun Feb
  18 22:46:32 PST 2007, "name"=>"Bob Dylan", "updated_on"=>Sun Feb 18 22:46:32 PST 2007, "id"=>10001},
  @errors=#, @errors={}>>>
  >> alb.save
  => true
  >> s = Song.new( :title => "Froggie Went A-Courtin’",
  ?> :length => 386,
  ?> :track_number => 13,
  ?> :album => alb )
  => # 
  @new_record_before_save=true, @attributes={"created_on"=>Sun Feb 18 22:50:47 PST 2007, "artist_id"=
  10001, "updated_on"=>Sun Feb 18 22:50:47 PST 2007, "id"=>10000, "year"=>1992, "release_name"=>"Good As
  I Been To You"}, @errors=#,
  @errors={}>, @artist=# 
  @attributes={"created_on"=>Sun Feb 18 22:46:32 PST 2007, "name"=>"Bob Dylan", "updated_on"=>Sun Feb 18
  22:46:32 PST 2007, "id"=>10001}, @errors=# 
  Artist:0x35589dc …>, @errors={}>>>, @attributes={"created_on"=>nil, "track_number"=>13, "title"=
  "Froggie Went A-Courtin’", "updated_on"=>nil, "album_id"=>10000, "length"=>386}>
  >> s.save
  => true

  接着,创建一些标签。记住,插件为您定义 Tag 模型,因此您可以像定义其他模型那样创建标签:  

>> t1 = Tag.new( :name => "male vocalist" )
  => #"male vocalist"}>
  >> t1.save
  => true
  >> t2 = Tag.new( :name => "children’s songs" )
  => #"children’s songs"}>
  >> t2.save
  => true

  最后,将这些标签与一个模型关联,例如,一首歌曲:  

>> s.tags << t1
  => [#"male
  vocalist", "id"=>10000}, @errors=#,
  @errors={}>>]
  >> s.tags << t2
  => [#"male
  vocalist", "id"=>10000}, @errors=#,
  @errors={}>>, # 
  @attributes={"name"=>"children’s songs", "id"=>10001}, @errors=# 
  @base=#, @errors={}>>]
  >> s.tags.count
  => 2

  当您添加 acts_as_taggable helper 时,就将 << 方法(记住,Ruby 中调用对象的任何东西都是方法,包括 <<)添加到 Artist 模型了。记住,它通过为模型添加 :has_many :tags helper 添加附加运算符(方法!)。这样,您就给“Bob Dylan”艺术家对象添加了两个标签。  

>> a.tags
  => [#"male
  vocalist", "id"=>10000}, @errors=#,
  @errors={}>>, # 
  @attributes={"name"=>"children’s songs", "id"=>10001}, @errors=# 
  @base=#, @errors={}>>]
  >> a.tags.count
  => 2

  添加了为数据制作标签的功能,您就能利用应用程序完成许多事情了!花点时间浏览 Rails API 文档,熟悉关联方法为您的模型添加的所有方法。它们现在也使用您的标签了!

  但还可以更好。acts_as_taggable_on_steroids 插件添加了多个方便的方法供您使用,从而让开发工作更简单、更快速。设计这个插件旨在复制由原先的 acts_as_taggable 插件提供的功能。这意味着您能进行以下操作:  

>> a2 = Artist.new( :name => "The Flaming Lips" )
  => #nil,
  "name"=>"The Flaming Lips", "updated_on"=>nil}>
  >> a2.save
  => true
  >> a2.tag_list = "alternative, male vocalist"
  => "alternative, male vocalist"
  >> a2.save
  => true
  >> a2.tags.count
  => 2

  注意返回的两个艺术家对象 Bob Dylan 和 The Flaming Lips。用同样的方法添加您选择的四个、五个或更多艺术家,确保为它们做作标签。试着多次使用同样的标签,这样我们下面要用的标签群示例才有意义。

  预测对标签群的调用

  在大多数社会应用程序和基于大众分类法的应用程序中,显示标签数据最常用的方法之一就是标签群。您已经在站点如 Flickr 和 del.icio.us 上看到过这些了。标签群基本上是对某系统中标签的直观表示,其大小依据流行度(也即频率)决定。acts_as_taggable 插件提供了一个计算标签频率的名为 tag_counts 的简便方法。不过,插件的开发人员肯定对 MySQL 有偏见,因为 tag_counts 方法的定义包含了一个 find_by_sql 调用,它使用了带有聚合函数的无效 SQL。依据标准,Oracle 要求非聚合语句必须包含在 GROUP BY 子句中。因此,即使 Oracle 运行正常,tag_counts 也会中断。

  不过,希望还是有的;您只需将下面内容添加到 RAILS_ROOT/vendor/plugins/act_as_taggable_on_steroids 插件中的 init.rb 文件的末尾:

  require File.dirname(__FILE__) + ‘/lib/acts_as_taggable_override’

  然后,在 RAILS_ROOT/vendor/plugins/acts_as_taggable_on_steroids/lib 创建一个名为 acts_as_taggable_override.rb 的文件,将如下代码放进去: 

module ActiveRecord
  module Acts #:nodoc:
  module Taggable #:nodoc:
  module SingletonMethods
  def tag_counts(options = {})
  logger.debug{"Using overriden tag_counts method"}
  options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order
  start_at = sanitize_sql([‘taggings.created_at >= ?’, options[:start_at]]) if options[:start_at]
  end_at = sanitize_sql([‘taggings.created_at <= ?’, options[:end_at]]) if options[:end_at]
  options[:conditions] = sanitize_sql(options[:conditions]) if options[:conditions]
  conditions = [options[:conditions], start_at, end_at].compact.join(‘ and ‘)
  at_least = sanitize_sql([‘count(*) >= ?’, options[:at_least]]) if options[:at_least]
  at_most = sanitize_sql([‘count(*) <= ?’, options[:at_most]]) if options[:at_most]
  having = [at_least, at_most].compact.join(‘ and ‘)
  order = "order by #{options[:order]}" if options[:order]
  limit = sanitize_sql([‘limit ?’, options[:limit]]) if options[:limit]
  Tag.find_by_sql <<-END
  select tags.id, tags.name, count(*) as count
  from tags left outer join taggings on tags.id = taggings.tag_id
  left outer join #{table_name} on #{table_name}.id = taggings.taggable_id
  where taggings.taggable_type = ‘#{name}’
  #{"and #{conditions}" unless conditions.blank?}
  group by tags.id, tags.name
  having count(*) > 0 #{"and #{having}" unless having.blank?}
  #{order}
  END
  end
  end
  end
  end
  end

 

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐