X-Git-Url: https://git.njae.me.uk/?a=blobdiff_plain;f=vendor%2Frails%2Frailties%2Fdoc%2Fguides%2Fsource%2Fcreating_plugins%2Facts_as_yaffle.txt;fp=vendor%2Frails%2Frailties%2Fdoc%2Fguides%2Fsource%2Fcreating_plugins%2Facts_as_yaffle.txt;h=de116af7db92740ccf67e9bcd59704682cb54884;hb=d115f2e23823271635bad69229a42cd8ac68debe;hp=0000000000000000000000000000000000000000;hpb=37cb670bf3ddde90b214e591f100ed4446469484;p=depot.git diff --git a/vendor/rails/railties/doc/guides/source/creating_plugins/acts_as_yaffle.txt b/vendor/rails/railties/doc/guides/source/creating_plugins/acts_as_yaffle.txt new file mode 100644 index 0000000..de116af --- /dev/null +++ b/vendor/rails/railties/doc/guides/source/creating_plugins/acts_as_yaffle.txt @@ -0,0 +1,191 @@ +== Add an `acts_as_yaffle` method to Active Record == + +A common pattern in plugins is to add a method called 'acts_as_something' to models. In this case, you want to write a method called 'acts_as_yaffle' that adds a 'squawk' method to your models. + +To begin, set up your files so that you have: + +*vendor/plugins/yaffle/test/acts_as_yaffle_test.rb* + +[source, ruby] +------------------------------------------------------ +require File.dirname(__FILE__) + '/test_helper.rb' + +class ActsAsYaffleTest < Test::Unit::TestCase +end +------------------------------------------------------ + +*vendor/plugins/yaffle/lib/yaffle.rb* + +[source, ruby] +------------------------------------------------------ +require 'yaffle/acts_as_yaffle' +------------------------------------------------------ + +*vendor/plugins/yaffle/lib/yaffle/acts_as_yaffle.rb* + +[source, ruby] +------------------------------------------------------ +module Yaffle + # your code will go here +end +------------------------------------------------------ + +Note that after requiring 'acts_as_yaffle' you also have to include it into ActiveRecord::Base so that your plugin methods will be available to the rails models. + +One of the most common plugin patterns for 'acts_as_yaffle' plugins is to structure your file like so: + +*vendor/plugins/yaffle/lib/yaffle/acts_as_yaffle.rb* + +[source, ruby] +------------------------------------------------------ +module Yaffle + def self.included(base) + base.send :extend, ClassMethods + end + + module ClassMethods + # any method placed here will apply to classes, like Hickwall + def acts_as_something + send :include, InstanceMethods + end + end + + module InstanceMethods + # any method placed here will apply to instaces, like @hickwall + end +end +------------------------------------------------------ + +With structure you can easily separate the methods that will be used for the class (like `Hickwall.some_method`) and the instance (like `@hickwell.some_method`). + +=== Add a class method === + +This plugin will expect that you've added a method to your model named 'last_squawk'. However, the plugin users might have already defined a method on their model named 'last_squawk' that they use for something else. This plugin will allow the name to be changed by adding a class method called 'yaffle_text_field'. + +To start out, write a failing test that shows the behavior you'd like: + +*vendor/plugins/yaffle/test/acts_as_yaffle_test.rb* + +[source, ruby] +------------------------------------------------------ +require File.dirname(__FILE__) + '/test_helper.rb' + +class Hickwall < ActiveRecord::Base + acts_as_yaffle +end + +class Wickwall < ActiveRecord::Base + acts_as_yaffle :yaffle_text_field => :last_tweet +end + +class ActsAsYaffleTest < Test::Unit::TestCase + load_schema + + def test_a_hickwalls_yaffle_text_field_should_be_last_squawk + assert_equal "last_squawk", Hickwall.yaffle_text_field + end + + def test_a_wickwalls_yaffle_text_field_should_be_last_tweet + assert_equal "last_tweet", Wickwall.yaffle_text_field + end +end +------------------------------------------------------ + +To make these tests pass, you could modify your `acts_as_yaffle` file like so: + +*vendor/plugins/yaffle/lib/yaffle/acts_as_yaffle.rb* + +[source, ruby] +------------------------------------------------------ +module Yaffle + def self.included(base) + base.send :extend, ClassMethods + end + + module ClassMethods + def acts_as_yaffle(options = {}) + cattr_accessor :yaffle_text_field + self.yaffle_text_field = (options[:yaffle_text_field] || :last_squawk).to_s + end + end +end + +ActiveRecord::Base.send :include, Yaffle +------------------------------------------------------ + +=== Add an instance method === + +This plugin will add a method named 'squawk' to any Active Record objects that call 'acts_as_yaffle'. The 'squawk' method will simply set the value of one of the fields in the database. + +To start out, write a failing test that shows the behavior you'd like: + +*vendor/plugins/yaffle/test/acts_as_yaffle_test.rb* + +[source, ruby] +------------------------------------------------------ +require File.dirname(__FILE__) + '/test_helper.rb' + +class Hickwall < ActiveRecord::Base + acts_as_yaffle +end + +class Wickwall < ActiveRecord::Base + acts_as_yaffle :yaffle_text_field => :last_tweet +end + +class ActsAsYaffleTest < Test::Unit::TestCase + load_schema + + def test_a_hickwalls_yaffle_text_field_should_be_last_squawk + assert_equal "last_squawk", Hickwall.yaffle_text_field + end + + def test_a_wickwalls_yaffle_text_field_should_be_last_tweet + assert_equal "last_tweet", Wickwall.yaffle_text_field + end + + def test_hickwalls_squawk_should_populate_last_squawk + hickwall = Hickwall.new + hickwall.squawk("Hello World") + assert_equal "squawk! Hello World", hickwall.last_squawk + end + + def test_wickwalls_squawk_should_populate_last_tweeted_at + wickwall = Wickwall.new + wickwall.squawk("Hello World") + assert_equal "squawk! Hello World", wickwall.last_tweet + end +end +------------------------------------------------------ + +Run this test to make sure the last two tests fail, then update 'acts_as_yaffle.rb' to look like this: + +*vendor/plugins/yaffle/lib/yaffle/acts_as_yaffle.rb* + +[source, ruby] +------------------------------------------------------ +module Yaffle + def self.included(base) + base.send :extend, ClassMethods + end + + module ClassMethods + def acts_as_yaffle(options = {}) + cattr_accessor :yaffle_text_field + self.yaffle_text_field = (options[:yaffle_text_field] || :last_squawk).to_s + send :include, InstanceMethods + end + end + + module InstanceMethods + def squawk(string) + write_attribute(self.class.yaffle_text_field, string.to_squawk) + end + end +end + +ActiveRecord::Base.send :include, Yaffle +------------------------------------------------------ + +.Editor's note: +NOTE: The use of `write_attribute` to write to the field in model is just one example of how a plugin can interact with the model, and will not always be the right method to use. For example, you could also use `send("#{self.class.yaffle_text_field}=", string.to_squawk)`.