aboutsummaryrefslogtreecommitdiffstats
path: root/railties/doc/guides/creating_plugins/preparation.txt
blob: 77e3a3561f0ccc1cdf0f2598a6d9734a46b26dba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
== Preparation ==

=== Create the basic app ===

In this tutorial we will create a basic rails application with 1 resource: bird.  Start out by building the basic rails app:

------------------------------------------------
rails plugin_demo
cd plugin_demo
script/generate scaffold bird name:string
rake db:migrate
script/server
------------------------------------------------

Then navigate to http://localhost:3000/birds.  Make sure you have a functioning rails app before continuing.

NOTE: The aforementioned instructions will work for sqlite3.  For more detailed instructions on how to create a rails app for other databases see the API docs.


=== Create the plugin ===

The built-in Rails plugin generator stubs out a new plugin. Pass the plugin name, either 'CamelCased' or 'under_scored', as an argument. Pass `\--with-generator` to add an example generator also.

This creates a plugin in 'vendor/plugins' including an 'init.rb' and 'README' as well as standard 'lib', 'task', and 'test' directories.

Examples:
----------------------------------------------
./script/generate plugin BrowserFilters
./script/generate plugin BrowserFilters --with-generator
----------------------------------------------

Later in the plugin we will create a generator, so go ahead and add the `\--with-generator` option now:

----------------------------------------------
script/generate plugin yaffle --with-generator
----------------------------------------------

You should see the following output:

----------------------------------------------
create  vendor/plugins/yaffle/lib
create  vendor/plugins/yaffle/tasks
create  vendor/plugins/yaffle/test
create  vendor/plugins/yaffle/README
create  vendor/plugins/yaffle/MIT-LICENSE
create  vendor/plugins/yaffle/Rakefile
create  vendor/plugins/yaffle/init.rb
create  vendor/plugins/yaffle/install.rb
create  vendor/plugins/yaffle/uninstall.rb
create  vendor/plugins/yaffle/lib/yaffle.rb
create  vendor/plugins/yaffle/tasks/yaffle_tasks.rake
create  vendor/plugins/yaffle/test/core_ext_test.rb
create  vendor/plugins/yaffle/generators
create  vendor/plugins/yaffle/generators/yaffle
create  vendor/plugins/yaffle/generators/yaffle/templates
create  vendor/plugins/yaffle/generators/yaffle/yaffle_generator.rb
create  vendor/plugins/yaffle/generators/yaffle/USAGE
----------------------------------------------

For this plugin you won't need the file 'vendor/plugins/yaffle/lib/yaffle.rb' so you can delete that.

----------------------------------------------
rm vendor/plugins/yaffle/lib/yaffle.rb
----------------------------------------------

.Editor's note:
NOTE: Many plugin authors prefer to keep this file, and add all of the require statements in it.  That way, they only line in init.rb would be `require "yaffle"`. If you are developing a plugin that has a lot of files in the lib directory, you may want to create a subdirectory like lib/yaffle and store your files in there.  That way your init.rb file stays clean


=== Setup the plugin for testing ===

Testing plugins that use the entire Rails stack can be complex, and the generator doesn't offer any help.  In this tutorial you will learn how to test your plugin against multiple different adapters using ActiveRecord.  This tutorial will not cover how to use fixtures in plugin tests.

To setup your plugin to allow for easy testing you'll need to add 3 files:

 * A 'database.yml' file with all of your connection strings.
 * A 'schema.rb' file with your table definitions.
 * A test helper that sets up the database before your tests.

For this plugin you'll need 2 tables/models, Hickwalls and Wickwalls, so add the following files:

*vendor/plugins/yaffle/test/database.yml:*

----------------------------------------------
sqlite:
  :adapter: sqlite
  :dbfile: yaffle_plugin.sqlite.db

sqlite3:
  :adapter: sqlite3
  :dbfile: yaffle_plugin.sqlite3.db

postgresql:
  :adapter: postgresql
  :username: postgres
  :password: postgres
  :database: yaffle_plugin_test
  :min_messages: ERROR

mysql:
  :adapter: mysql
  :host: localhost
  :username: rails
  :password:
  :database: yaffle_plugin_test
----------------------------------------------

*vendor/plugins/yaffle/test/test_helper.rb:*

[source, ruby]
----------------------------------------------
ActiveRecord::Schema.define(:version => 0) do
  create_table :hickwalls, :force => true do |t|
    t.string :name
    t.string :last_squawk
    t.datetime :last_squawked_at
  end
  create_table :wickwalls, :force => true do |t|
    t.string :name
    t.string :last_tweet
    t.datetime :last_tweeted_at
  end
end

# File: vendor/plugins/yaffle/test/test_helper.rb

ENV['RAILS_ENV'] = 'test'
ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..'

require 'test/unit'
require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb'))

config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")

db_adapter = ENV['DB']

# no db passed, try one of these fine config-free DBs before bombing.
db_adapter ||=
  begin
    require 'rubygems'
    require 'sqlite'
    'sqlite'
  rescue MissingSourceFile
    begin
      require 'sqlite3'
      'sqlite3'
    rescue MissingSourceFile
    end
  end

if db_adapter.nil?
  raise "No DB Adapter selected. Pass the DB= option to pick one, or install Sqlite or Sqlite3."
end

ActiveRecord::Base.establish_connection(config[db_adapter])

load(File.dirname(__FILE__) + "/schema.rb")

require File.dirname(__FILE__) + '/../init.rb'

class Hickwall < ActiveRecord::Base
  acts_as_yaffle
end

class Wickwall < ActiveRecord::Base
  acts_as_yaffle :yaffle_text_field => :last_tweet, :yaffle_date_field => :last_tweeted_at
end
----------------------------------------------