Permalink
Browse files

Add to_key and to_param methods to ActiveModel::Conversion.

  • Loading branch information...
1 parent f81c6bc commit 9dd67fce25d3993a0ee494506ba246a45d395e3f @josevalim josevalim committed Feb 21, 2010
@@ -1,19 +1,44 @@
module ActiveModel
- # If your object is already designed to implement all of the Active Model featurs
- # include this module in your Class.
- #
- # class MyClass
+ # Handle default conversions: to_model, to_key and to_param.
+ #
+ # == Example
+ #
+ # Let's take for example this non persisted object.
+ #
+ # class ContactMessage
# include ActiveModel::Conversion
+ #
+ # # Always a new record, since it's not persisted in the DB.
+ # def new_record?
+ # true
+ # end
# end
- #
- # Returns self to the <tt>:to_model</tt> method.
- #
- # If your model does not act like an Active Model object, then you should define
- # <tt>:to_model</tt> yourself returning a proxy object that wraps your object
- # with Active Model compliant methods.
+ #
+ # cm = ContactMessage.new
+ # cm.to_model == self #=> true
+ # cm.to_key #=> nil
+ # cm.to_param #=> nil
+ #
module Conversion
+ # If your object is already designed to implement all of the Active Model you can use
+ # the default to_model implementation, which simply returns self.
+ #
+ # If your model does not act like an Active Model object, then you should define
+ # <tt>:to_model</tt> yourself returning a proxy object that wraps your object
+ # with Active Model compliant methods.
def to_model
self
end
+
+ # Returns an Enumerable of all (primary) key attributes or nil if new_record? is true
+ def to_key
+ new_record? ? nil : [id]
+ end
+
+ # Returns a string representing the object's key suitable for use in URLs,
+ # or nil if new_record? is true
+ def to_param
+ to_key ? to_key.join('-') : nil
+ end
end
end
@@ -0,0 +1,25 @@
+require 'cases/helper'
+require 'models/contact'
+
+class ConversionTest < ActiveModel::TestCase
+ test "to_model default implementation returns self" do
+ contact = Contact.new
+ assert_equal contact, contact.to_model
+ end
+
+ test "to_key default implementation returns nil for new records" do
+ assert_nil Contact.new.to_key
+ end
+
+ test "to_key default implementation returns the id in an array for persisted records" do
+ assert_equal [1], Contact.new(:new_record => false, :id => 1).to_key
+ end
+
+ test "to_param default implementation returns nil for new records" do
+ assert_nil Contact.new.to_param
+ end
+
+ test "to_param default implementation returns a string of ids for persisted records" do
+ assert_equal "1", Contact.new(:new_record => false, :id => 1).to_param
+ end
+end
@@ -1,24 +1,11 @@
-require "cases/helper"
+require 'cases/helper'
class LintTest < ActiveModel::TestCase
include ActiveModel::Lint::Tests
class CompliantModel
extend ActiveModel::Naming
-
- def to_model
- self
- end
-
- def to_key
- new_record? ? nil : [id]
- end
-
- def to_param
- return nil if to_key.nil?
- # some default for CPKs, real implementations will differ
- to_key.length > 1 ? to_key.join('-') : to_key.first.to_s
- end
+ include ActiveModel::Conversion
def valid?() true end
def new_record?() true end
@@ -1,7 +1,13 @@
class Contact
- attr_accessor :name, :age, :created_at, :awesome, :preferences
+ include ActiveModel::Conversion
+
+ attr_accessor :id, :name, :age, :created_at, :awesome, :preferences, :new_record
def initialize(options = {})
options.each { |name, value| send("#{name}=", value) }
end
+
+ def new_record?
+ defined?(@new_record) ? @new_record : true
+ end
end
@@ -50,7 +50,7 @@ module InstanceMethods
# This method also takes custom primary keys specified via
# the +set_primary_key+ into account.
def to_key
- new_record? ? nil : [ self.send(self.class.primary_key) ]
+ new_record? ? nil : [ self.primary_key ]
end
end

0 comments on commit 9dd67fc

Please sign in to comment.