开发者

Myopia WRT has_many :through

I'm just not seeing what's wrong with this code. Here is the spec:

it "Meta tags should not duplicate for a particular page" do
  p1 = Page.create!(:title => 'first page', :body_text => 'p1 body text')
  p2 = Page.create!(:title => 'second page', :body_text => 'p2 body text')
  p1.add_meta_tag(:content => 'alexa', :description => '100')
  p2.add_meta_tag(:content => 'alexa', :description => '200')

  p1.meta_tags.where("content = 'alexa'").should ha开发者_运维百科ve(1).record
  p2.meta_tags.where("content = 'alexa'").should have(1).record
end

The models are:

class Page < AR::Base
  has_many :page_to_meta_tag_maps
  has_many :meta_tags, :through => :page_to_meta_tag_maps

  # BONEHEAD PROBLEM PROBABLY HERE...
  def add_meta_tag(options)
    @cm = self.meta_tags.where(["content=?", options[:content]]).first
    @current_meta = @cm || MetaTag.create(options)
    @current_meta.description = options[:description]
    self.meta_tags << @current_meta
  end
end

class PageToMetaTagMap < ActiveRecord::Base
  belongs_to :page
  belongs_to :meta_tag
end

class MetaTag < ActiveRecord::Base
  attr_accessible :content, :description

  has_many :page_to_meta_tag_maps
  has_many :pages, :through => :page_to_meta_tag_maps
end

It's failing the spec saying there are 2 records, not 1. The logs show that Rails is doing an INSERT each time, and @cm in the BONEHEAD PROBLEM area is always nil. I must be fundamentally misunderstanding something here.

I love it when this happens and there's time pressure :(


I changed the BONEHEAD PROBLEM code to:

def add_meta_tag(options)
  @current_meta = self.meta_tags.where(["content=?", options[:content]]).first
  if @current_meta
    @current_meta.description = options[:description]
    @current_meta.save
  else
    @current_meta = MetaTag.create(options)
    self.meta_tags << @current_meta
  end
end

which solves the problem. I can't help but think that there's a better way...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜