views:

293

answers:

2

I'm writing a small CMS as a Rails test project (also planning to use it for my personal website). I want SEO-friendly URLs so I have a test to verify that permalinks are automatically being created based on a page's title (e.g. About Us => about-us). I can't figure out why this test is failing, however. Here's the code (I'm using Rails 2.3.2):

# page_test.rb
# note I am using the "shoulda" framework
require 'test_helper'

class PageTest < ActiveSupport::TestCase
  should_validate_presence_of :title, :permalink, :content
  should_validate_uniqueness_of :title

  should "create permalink automatically" do
    p = pages(:sample_page)
    p.save

    assert_equal "sample-page", p.permalink
  end
end

# pages.yml
sample_page:
  title: Sample Page
  permalink: # gets automatically created by model
  content: This is a sample page

# page.rb
class Page < ActiveRecord::Base
  validates_presence_of :title, :permalink, :content
  validates_uniqueness_of :title

  before_save :generate_permalink

  private

  def generate_permalink
    self.permalink = self.title.parameterize
  end
end

What happens is that the permalink is nil, instead of "sample-page" like it's supposed to be. It works, however, if I manually put the permalink in the fixture and change the test around, for example:

p - pages(:sample_page)
p.title = "Contact Us"
p.save

assert_equal "contact-us", p.permalink

I could fix it like this, but I'm wondering why it's not firing the before_save method for the original test.

A: 

Does it work if you remove the empty permalink: key from your pages.yml file?

John Topley
Nope, same error. It expects "sample-page" but gets nil
Wayne M
Is the sample page getting saved in the test database when you run the test?
John Topley
Hmm okay I think I see the issue - it's not saving because the permalink is blank (I changed save to save! and it threw an error). The before_save method should fix that, however.. I'm not sure why before_save isn't getting called prior to actually saving it.
Wayne M
+1  A: 

Alright, I was able to figure it out. I needed to use before_validation as the callback and not before_save

Wayne M