activerecord-tablefree 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.travis.yml +10 -0
- data/Appraisals +11 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +25 -0
- data/README.md +175 -0
- data/Rakefile +48 -0
- data/activerecord-tablefree.gemspec +46 -0
- data/features/basic_integration.feature +16 -0
- data/features/step_definitions/rails_steps.rb +141 -0
- data/features/step_definitions/tablefree.rb +37 -0
- data/features/step_definitions/web_steps.rb +140 -0
- data/features/support/env.rb +15 -0
- data/features/support/paths.rb +28 -0
- data/features/support/rails.rb +52 -0
- data/features/support/selectors.rb +19 -0
- data/gemfiles/rails50.gemfile +11 -0
- data/gemfiles/rails51.gemfile +11 -0
- data/init.rb +4 -0
- data/lib/activerecord-tablefree.rb +318 -0
- data/lib/activerecord-tablefree/version.rb +7 -0
- data/spec/lib/activerecord-tablefree_spec.rb +284 -0
- data/spec/spec_helper.rb +2 -0
- metadata +300 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: de6c056db0ef936941da8a47564f72372294315f
|
4
|
+
data.tar.gz: 24f73ee3c29efd71c659f99b3d5090ea9da6f1cf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 14e50f61f2f1873d22a190950873ed48c3fcea691c0cf56f0b469450d21c4e24773e436459644d416da752434ad5fd2eea467feaf0e607b0c19633d46fc2fe40
|
7
|
+
data.tar.gz: b196ba371f8dc6a78bb9a2f7e3fc128c9eb3515a90c73303fc8514fa1560a4a49a98b81d4a56f0537a4b882ab72cdcda93a4ec57b19868eccd330b33dad45c2f
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --backtrace --format doc
|
data/.travis.yml
ADDED
data/Appraisals
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
LICENSE
|
3
|
+
|
4
|
+
The MIT License
|
5
|
+
|
6
|
+
Copyright (c) 2008 Jarl Friis. (released as activerecord-tableless)
|
7
|
+
Copyright (c) 2017 Peter Boling, Bolt Threads.
|
8
|
+
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
11
|
+
in the Software without restriction, including without limitation the rights
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
14
|
+
furnished to do so, subject to the following conditions:
|
15
|
+
|
16
|
+
The above copyright notice and this permission notice shall be included in
|
17
|
+
all copies or substantial portions of the Software.
|
18
|
+
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
25
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,175 @@
|
|
1
|
+
ActiveRecord Tablefree
|
2
|
+
======================
|
3
|
+
|
4
|
+
| Project | Dynamoid |
|
5
|
+
|------------------------ | ----------------- |
|
6
|
+
| gem name | dynamoid |
|
7
|
+
| license | MIT |
|
8
|
+
| download rank | [](https://rubygems.org/gems/activerecord-tablefree) |
|
9
|
+
| version | [](http://badge.fury.io/rb/activerecord-tablefree) |
|
10
|
+
| dependencies | [](https://gemnasium.com/github.com/boltthreads/activerecord-tablefree) |
|
11
|
+
| code quality | [](https://codeclimate.com/github/boltthreads/activerecord-tablefree) |
|
12
|
+
| continuous integration | [](http://travis-ci.org/boltthreads/activerecord-tablefree) |
|
13
|
+
| test coverage | [](https://coveralls.io/github/boltthreads/activerecord-tablefree?branch=master) |
|
14
|
+
| triage helpers | [](https://www.codetriage.com/boltthreads/activerecord-tablefree) |
|
15
|
+
| homepage | [https://github.com/boltthreads/activerecord-tablefree](https://github.com/boltthreads/activerecord-tablefree) |
|
16
|
+
| documentation | [http://rdoc.info/github/boltthreads/activerecord-tablefree/frames](http://rdoc.info/github/boltthreads/activerecord-tablefree/frames) |
|
17
|
+
|
18
|
+
A simple implementation of the ActiveRecord Tableless pattern for any
|
19
|
+
Rails project or other Ruby project that uses ActiveRecord.
|
20
|
+
|
21
|
+
Why, why, why
|
22
|
+
-------------
|
23
|
+
|
24
|
+
Why would you ever consider this gem as opposed to ActiveModel.
|
25
|
+
|
26
|
+
ActiveModel::Model does not support relations and nested attributes.
|
27
|
+
|
28
|
+
|
29
|
+
Installation
|
30
|
+
------------
|
31
|
+
|
32
|
+
ActiveRecord Tablefree is distributed as a gem, which is how it should
|
33
|
+
be used in your app.
|
34
|
+
|
35
|
+
Include the gem in your Gemfile:
|
36
|
+
|
37
|
+
gem "activerecord-tablefree", "~> 1.0"
|
38
|
+
|
39
|
+
|
40
|
+
Supported Versions
|
41
|
+
------------------
|
42
|
+
|
43
|
+
Supported ruby version are
|
44
|
+
|
45
|
+
* **2.2.x** series higher than 2.2.2
|
46
|
+
* **2.3.x** series
|
47
|
+
|
48
|
+
If you are using Ruby version < 2.2.2 you can use the gem version <
|
49
|
+
2.0 like this
|
50
|
+
|
51
|
+
gem "activerecord-tablefree", "~> 1.0.0"
|
52
|
+
|
53
|
+
Supported ActiveRecord versions are
|
54
|
+
|
55
|
+
* **3.0.x** series
|
56
|
+
* **3.2.x** series
|
57
|
+
* **4.1.x** series
|
58
|
+
* **4.2.x** series
|
59
|
+
|
60
|
+
If you are using ActiveRecord 2.3.x series you can use the gem version <
|
61
|
+
2.0 like this
|
62
|
+
|
63
|
+
gem "activerecord-tablefree", "~> 1.0.0"
|
64
|
+
|
65
|
+
You may be able to make it work with 3.1.x, but you should expect to
|
66
|
+
put some time in it.
|
67
|
+
|
68
|
+
TODO
|
69
|
+
----
|
70
|
+
|
71
|
+
* Support Rails 5.x series
|
72
|
+
|
73
|
+
Usage
|
74
|
+
-----
|
75
|
+
|
76
|
+
Define a model like this:
|
77
|
+
|
78
|
+
class ContactMessage < ActiveRecord::Base
|
79
|
+
has_no_table
|
80
|
+
column :name, :string
|
81
|
+
column :email, :string
|
82
|
+
validates_presence_of :name, :email
|
83
|
+
end
|
84
|
+
|
85
|
+
You can now use the model in a view like this:
|
86
|
+
|
87
|
+
<%= form_for :message, @message do |f| %>
|
88
|
+
Your name: <%= f.text_field :name %>
|
89
|
+
Your email: <%= f.text_field :email %>
|
90
|
+
<% end %>
|
91
|
+
|
92
|
+
And in the controller:
|
93
|
+
|
94
|
+
def message
|
95
|
+
@message = ContactMessage.new
|
96
|
+
if request.post?
|
97
|
+
@message.attributes = params[:message]
|
98
|
+
if @message.valid?
|
99
|
+
# Process the message...
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
If you wish (this is not recommended), you can pretend you have a succeeding database by using
|
105
|
+
|
106
|
+
has_no_table :database => :pretend_success
|
107
|
+
|
108
|
+
|
109
|
+
Development
|
110
|
+
-----------
|
111
|
+
|
112
|
+
To start developing, please download the source code
|
113
|
+
|
114
|
+
git clone git://github.com/boltthreads/activerecord-tablefree.git
|
115
|
+
|
116
|
+
Install development libraries
|
117
|
+
|
118
|
+
sudo apt-get install -y libsqlite3-dev libxml2-dev libxslt-dev
|
119
|
+
|
120
|
+
When downloaded, you can start issuing the commands like
|
121
|
+
|
122
|
+
bundle install
|
123
|
+
bundle update
|
124
|
+
bundle exec appraisal generate
|
125
|
+
bundle exec appraisal install
|
126
|
+
bundle exec appraisal rake all
|
127
|
+
|
128
|
+
Or you can see what other options are there:
|
129
|
+
|
130
|
+
bundle exec rake -T
|
131
|
+
|
132
|
+
Publishing gem
|
133
|
+
--------------
|
134
|
+
|
135
|
+
```
|
136
|
+
gem bump -v pre
|
137
|
+
```
|
138
|
+
|
139
|
+
Verify everything is OK.
|
140
|
+
|
141
|
+
```
|
142
|
+
gem build activerecord-tablefree.gemspec
|
143
|
+
```
|
144
|
+
|
145
|
+
Verify everything is OK.
|
146
|
+
|
147
|
+
```
|
148
|
+
gem release -t
|
149
|
+
```
|
150
|
+
|
151
|
+
|
152
|
+
History
|
153
|
+
-------
|
154
|
+
|
155
|
+
Originally this code was implemented for Rails 2 by Kenneth
|
156
|
+
Kalmer. For Rails 3 the need for this functionality was reduced
|
157
|
+
dramatically due to the introduction of ActiveModel. But because the
|
158
|
+
ActiveModel does not support relations and nested attributes the
|
159
|
+
existence of this gem is still justified.
|
160
|
+
|
161
|
+
Rails 3 and 4 support is provided in the [activerecord-tableless gem](https://github.com/softace/activerecord-tableless), by [Jarl Friis](https://github.com/jarl-dk).
|
162
|
+
|
163
|
+
This gem is a Rails 5 compatible update, and renaming of that gem.
|
164
|
+
|
165
|
+
For a history of technical implementation details feel free to take a
|
166
|
+
look in the git log :-)
|
167
|
+
|
168
|
+
|
169
|
+
Copyright
|
170
|
+
---------
|
171
|
+
|
172
|
+
Copyright (c) Jarl Friis.
|
173
|
+
Copyright (c) Peter Boling, Bolt Threads.
|
174
|
+
|
175
|
+
The license is MIT. See LICENSE.txt for further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'appraisal'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'cucumber/rake/task'
|
6
|
+
|
7
|
+
desc 'Default: clean, all.'
|
8
|
+
task :default => [:clean, :all]
|
9
|
+
|
10
|
+
desc 'Test the activerecord-tablefree on all supported Rails versions.'
|
11
|
+
task :all do |t|
|
12
|
+
# TODO: cucumber feature specs appear to be written for Rails 2, and will need an overhaul for Rails 5.
|
13
|
+
if ENV['BUNDLE_GEMFILE']
|
14
|
+
exec('rake test spec')
|
15
|
+
# exec('rake test spec cucumber')
|
16
|
+
else
|
17
|
+
Rake::Task["appraisal:install"].execute
|
18
|
+
exec('rake appraisal test spec')
|
19
|
+
# exec('rake appraisal test spec cucumber')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'Test the activerecord-tablefree plugin.'
|
24
|
+
Rake::TestTask.new(:test) do |t|
|
25
|
+
t.libs << 'lib' << 'profile'
|
26
|
+
t.pattern = 'test/**/*_test.rb'
|
27
|
+
t.verbose = true
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Run specs"
|
31
|
+
RSpec::Core::RakeTask.new do |t|
|
32
|
+
t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
|
33
|
+
# Put spec opts in a file named .rspec in root
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'Run integration test'
|
37
|
+
Cucumber::Rake::Task.new do |t|
|
38
|
+
t.cucumber_opts = %w{--format progress}
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'Clean up files.'
|
42
|
+
task :clean do |t|
|
43
|
+
FileUtils.rm_rf "doc"
|
44
|
+
FileUtils.rm_rf "tmp"
|
45
|
+
FileUtils.rm_rf "pkg"
|
46
|
+
FileUtils.rm_rf "public"
|
47
|
+
Dir.glob("activerecord-tablefree-*.gem").each{|f| FileUtils.rm f }
|
48
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
$LOAD_PATH.push File.expand_path("../lib", __FILE__)
|
3
|
+
require 'activerecord-tablefree/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = 'activerecord-tablefree'
|
7
|
+
gem.version = ActiveRecord::Tablefree::VERSION
|
8
|
+
gem.platform = Gem::Platform::RUBY
|
9
|
+
gem.authors = ["Jarl Friis", "Kenneth Kalmer", "Michal Zima", "Peter Boling"]
|
10
|
+
gem.email = ["jarl@softace.dk", "peter.boling@gmail.com"]
|
11
|
+
gem.homepage = "https://github.com/boltthreads/activerecord-tablefree"
|
12
|
+
gem.summary = %q{A library for implementing tablefree ActiveRecord models}
|
13
|
+
gem.description = %q{ActiveRecord Tablefree Models provides a simple mixin for creating models that are not bound to the database. This approach is useful for taking advantage of the features of ActiveRecord such as validation, relationships, etc.}
|
14
|
+
gem.license = 'MIT'
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($\)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.has_rdoc = true
|
20
|
+
|
21
|
+
gem.require_paths = ["lib"]
|
22
|
+
|
23
|
+
gem.add_runtime_dependency('activerecord', '>= 3.0.0')
|
24
|
+
|
25
|
+
gem.add_development_dependency('bundler', '~> 1.16.0')
|
26
|
+
gem.add_development_dependency('rake', '~> 0', '> 0')
|
27
|
+
|
28
|
+
# gem.add_development_dependency("rails") # This is in the appraisal gemfiles
|
29
|
+
gem.add_development_dependency('sqlite3', '~> 1.3')
|
30
|
+
|
31
|
+
gem.add_development_dependency('appraisal', '~> 1.0')
|
32
|
+
gem.add_development_dependency('cucumber', '~> 1.1')
|
33
|
+
gem.add_development_dependency('rspec', '~> 3.1')
|
34
|
+
gem.add_development_dependency('rspec-collection_matchers', '~> 1.0')
|
35
|
+
gem.add_development_dependency('aruba', '~> 0.5')
|
36
|
+
|
37
|
+
gem.add_development_dependency('nokogiri', '~> 1.0')
|
38
|
+
gem.add_development_dependency('capybara', '~> 0.0')
|
39
|
+
gem.add_development_dependency('gem-release', '~> 0.7.4')
|
40
|
+
gem.add_development_dependency('wwtd')
|
41
|
+
gem.add_development_dependency('rails')
|
42
|
+
gem.add_development_dependency('listen')
|
43
|
+
|
44
|
+
# gem.add_development_dependency('launchy', '~> 2.1')
|
45
|
+
# gem.add_development_dependency('debugger')
|
46
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: Rails integration
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I generate a new rails application
|
5
|
+
And I run a "scaffold" generator to generate a "User" scaffold with "name:string"
|
6
|
+
And I delete all migrations
|
7
|
+
And I update my new user model to be tablefree
|
8
|
+
And I update my users controller to render instead of redirect
|
9
|
+
|
10
|
+
Scenario: Work as normal model
|
11
|
+
And I start the rails application
|
12
|
+
When I go to the new user page
|
13
|
+
And I fill in "Name" with "something"
|
14
|
+
And I press "Create"
|
15
|
+
Then I should see "Name: something"
|
16
|
+
|
@@ -0,0 +1,141 @@
|
|
1
|
+
Given /^I generate a new rails application$/ do
|
2
|
+
steps %{
|
3
|
+
When I successfully run `bundle exec #{new_application_command(APP_NAME)}`
|
4
|
+
And I cd to "#{APP_NAME}"
|
5
|
+
And I turn off class caching
|
6
|
+
And I fix the application.rb for 3.0.12
|
7
|
+
And I write to "Gemfile" with:
|
8
|
+
"""
|
9
|
+
source "http://rubygems.org"
|
10
|
+
gem "rails", "#{framework_version}"
|
11
|
+
gem "sqlite3"
|
12
|
+
gem "capybara"
|
13
|
+
gem "gherkin"
|
14
|
+
"""
|
15
|
+
And I configure the application to use "activerecord-tablefree" from this project
|
16
|
+
And I reset Bundler environment variable
|
17
|
+
And I successfully run `bundle install --local`
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
Given "I fix the application.rb for 3.0.12" do
|
22
|
+
##See https://github.com/rails/rails/issues/9619
|
23
|
+
in_current_dir do
|
24
|
+
File.open("config/application.rb", "a") do |f|
|
25
|
+
f << "ActionController::Base.config.relative_url_root = ''"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Given /^I run a "(.*?)" generator to generate a "(.*?)" scaffold with "(.*?)"$/ do |generator_name, model_name, attributes|
|
31
|
+
step %[I successfully run `bundle exec #{generator_command} #{generator_name} #{model_name} #{attributes}`]
|
32
|
+
end
|
33
|
+
|
34
|
+
Given /^I start the rails application$/ do
|
35
|
+
in_current_dir do
|
36
|
+
require "./config/environment"
|
37
|
+
require "capybara/rails"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
Given /^I reload my application$/ do
|
42
|
+
Rails::Application.reload!
|
43
|
+
end
|
44
|
+
|
45
|
+
When %r{I turn off class caching} do
|
46
|
+
in_current_dir do
|
47
|
+
file = "config/environments/test.rb"
|
48
|
+
config = IO.read(file)
|
49
|
+
config.gsub!(%r{^\s*config.cache_classes.*$},
|
50
|
+
"config.cache_classes = false")
|
51
|
+
File.open(file, "w"){|f| f.write(config) }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
Given /^I update my application to use Bundler$/ do
|
56
|
+
if framework_version?("2")
|
57
|
+
boot_config_template = File.read('features/support/fixtures/boot_config.txt')
|
58
|
+
preinitializer_template = File.read('features/support/fixtures/preinitializer.txt')
|
59
|
+
gemfile_template = File.read('features/support/fixtures/gemfile.txt')
|
60
|
+
in_current_dir do
|
61
|
+
content = File.read("config/boot.rb").sub(/Rails\.boot!/, boot_config_template)
|
62
|
+
File.open("config/boot.rb", "w") { |file| file.write(content) }
|
63
|
+
File.open("config/preinitializer.rb", "w") { |file| file.write(preinitializer_template) }
|
64
|
+
File.open("Gemfile", "w") { |file| file.write(gemfile_template.sub(/RAILS_VERSION/, framework_version)) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
Then /^the file at "([^"]*)" should be the same as "([^"]*)"$/ do |web_file, path|
|
70
|
+
expected = IO.binread(path)
|
71
|
+
actual = if web_file.match %r{^https?://}
|
72
|
+
Net::HTTP.get(URI.parse(web_file))
|
73
|
+
else
|
74
|
+
visit(web_file)
|
75
|
+
page.source
|
76
|
+
end
|
77
|
+
actual.should == expected
|
78
|
+
end
|
79
|
+
|
80
|
+
When /^I configure the application to use "([^\"]+)" from this project$/ do |name|
|
81
|
+
append_to_gemfile "gem '#{name}', :path => '#{PROJECT_ROOT}'"
|
82
|
+
steps %{And I run `bundle install --local`}
|
83
|
+
end
|
84
|
+
|
85
|
+
When /^I configure the application to use "([^\"]+)"$/ do |gem_name|
|
86
|
+
append_to_gemfile "gem '#{gem_name}'"
|
87
|
+
end
|
88
|
+
|
89
|
+
When /^I append gems from Appraisal Gemfile$/ do
|
90
|
+
File.read(ENV['BUNDLE_GEMFILE']).split(/\n/).each do |line|
|
91
|
+
if line =~ /^gem "(?!rails|appraisal)/
|
92
|
+
append_to_gemfile line.strip
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
When /^I comment out the gem "(.*?)" from the Gemfile$/ do |gemname|
|
98
|
+
comment_out_gem_in_gemfile gemname
|
99
|
+
end
|
100
|
+
|
101
|
+
Then /^the result of "(.*?)" should be the same as "(.*?)"$/ do |rails_expr, path|
|
102
|
+
expected = IO.binread(path)
|
103
|
+
actual = eval "#{rails_expr}"
|
104
|
+
actual.should == expected
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
module FileHelpers
|
109
|
+
def append_to(path, contents)
|
110
|
+
in_current_dir do
|
111
|
+
File.open(path, "a") do |file|
|
112
|
+
file.puts
|
113
|
+
file.puts contents
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def append_to_gemfile(contents)
|
119
|
+
append_to('Gemfile', contents)
|
120
|
+
end
|
121
|
+
|
122
|
+
def comment_out_gem_in_gemfile(gemname)
|
123
|
+
in_current_dir do
|
124
|
+
gemfile = File.read("Gemfile")
|
125
|
+
gemfile.sub!(/^(\s*)(gem\s*['"]#{gemname})/, "\\1# \\2")
|
126
|
+
File.open("Gemfile", 'w'){ |file| file.write(gemfile) }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def transform_file(filename)
|
131
|
+
if File.exists?(filename)
|
132
|
+
content = File.read(filename)
|
133
|
+
File.open(filename, "w") do |f|
|
134
|
+
content = yield(content)
|
135
|
+
f.write(content)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
World(FileHelpers)
|