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...
精彩评论