anaf_habtm 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ gem 'rails', '3.0.0.beta4'
2
+ gem 'sqlite3-ruby', :require => 'sqlite3'
3
+ gem 'jeweler'
4
+
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,57 @@
1
+ == HABTM Example
2
+
3
+ Complex forms on a HABTM association.
4
+
5
+ Using code borrowed from Pat (http://patshaughnessy.net), whose view_mapper
6
+ finally taught this hobbyist hacker to write forms.
7
+
8
+ Hopefully this will fit snugly into someone else's gem
9
+
10
+ == Installation
11
+
12
+ * Install as a gem:
13
+ # Add to your Gemfile
14
+ gem "anaf_habtm", :git => "git://github.com/tylergannon/anaf_habtm.git"
15
+ * or as a plugin
16
+ rails plugin install git://github.com/tylergannon/anaf_habtm.git
17
+ rake anaf_habtm:install # copies some javascript to public
18
+
19
+
20
+ Add the following to your layout:
21
+ <%= javascript_include_tag 'nested_attributes.js' %>
22
+
23
+ == Usage
24
+
25
+ Inside your model, call anaf_habtm just as you would call has_and_belongs_to_many,
26
+ except now you need to offer a code block telling rails what to do with each object.
27
+ The plugin will handle deleting stuff.
28
+
29
+ # Basically, your code block needs to return an object of the correct
30
+ # type for your association collection, or else nil if your code
31
+ # determines that the object should be rejected.
32
+ class Customer < ActiveRecord::Base
33
+ anaf_habtm :orders, :autosave => true, :uniq => false do |params, order|
34
+ order = order ||= Order.new
35
+ order.attributes = params
36
+ logger.error params.inspect
37
+ order
38
+ end
39
+ end
40
+
41
+ class Order < ActiveRecord::Base
42
+ has_and_belongs_to_many :customers
43
+ anaf_habtm :items, :autosave => true, :uniq => false do |params, item|
44
+ logger.error "ITEM::: #{params.inspect}"
45
+ item ||= Item.find_or_create_by_name(params["name"])
46
+ end
47
+ end
48
+
49
+ == Additional info
50
+
51
+ See the example app at http://github.com/tylergannon/accepts-nested-attributes-habtm-example for more details.
52
+
53
+ Also check out Pat's view_mapper... it can generate the code you need inside your views.
54
+
55
+ http://github.com/patshaughnessy/view_mapper
56
+
57
+
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the anaf_habtm plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.libs << 'test'
12
+ t.pattern = 'test/**/*_test.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ desc 'Generate documentation for the anaf_habtm plugin.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'AnafHabtm'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
24
+ PKG_FILES = FileList[
25
+ '[a-zA-Z]*',
26
+ 'assets/**/*',
27
+ 'lib/**/*',
28
+ 'rails/**/*',
29
+ 'test/**/*'
30
+ ]
31
+
32
+ begin
33
+ require 'jeweler'
34
+ Jeweler::Tasks.new do |s|
35
+ s.name = "anaf_habtm"
36
+ s.version = "0.0.1"
37
+ s.author = "Tyler Gannon"
38
+ s.homepage = "http://github.com/tylergannon/anaf_habtm"
39
+ s.platform = Gem::Platform::RUBY
40
+ s.summary = "accepts_nested_attributes_for habtm"
41
+ s.files = PKG_FILES.to_a
42
+ s.require_path = "lib"
43
+ s.has_rdoc = false
44
+ s.extra_rdoc_files = ["README"]
45
+
46
+ end
47
+ rescue LoadError
48
+ puts "Jeweler not available. Install it with: gem install jeweler"
49
+ end
50
+
51
+
52
+
@@ -0,0 +1,54 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{anaf_habtm}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Tyler Gannon"]
12
+ s.date = %q{2010-07-09}
13
+ s.extra_rdoc_files = [
14
+ "README"
15
+ ]
16
+ s.files = [
17
+ "Gemfile",
18
+ "MIT-LICENSE",
19
+ "README",
20
+ "Rakefile",
21
+ "anaf_habtm.gemspec",
22
+ "assets/nested_attributes.js",
23
+ "install.rb",
24
+ "lib/active_record_extensions.rb",
25
+ "lib/anaf_habtm.rb",
26
+ "lib/application_helper_methods.rb",
27
+ "lib/hash.rb",
28
+ "lib/tasks/install.rake",
29
+ "rails/init.rb",
30
+ "test/anaf_habtm_test.rb",
31
+ "test/test_helper.rb",
32
+ "uninstall.rb"
33
+ ]
34
+ s.homepage = %q{http://github.com/tylergannon/anaf_habtm}
35
+ s.rdoc_options = ["--charset=UTF-8"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.7}
38
+ s.summary = %q{accepts_nested_attributes_for habtm}
39
+ s.test_files = [
40
+ "test/anaf_habtm_test.rb",
41
+ "test/test_helper.rb"
42
+ ]
43
+
44
+ if s.respond_to? :specification_version then
45
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
46
+ s.specification_version = 3
47
+
48
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
49
+ else
50
+ end
51
+ else
52
+ end
53
+ end
54
+
@@ -0,0 +1,14 @@
1
+ function add_child(element, child_name, new_child) {
2
+ $(child_name + '_children').insert({
3
+ bottom: new_child.replace(/NEW_RECORD/g, new Date().getTime())
4
+ });
5
+ }
6
+
7
+ function remove_child(element) {
8
+ var hidden_field = $(element).previous("input[type=hidden]");
9
+ if (hidden_field) {
10
+ hidden_field.value = '1';
11
+ }
12
+ $(element).up(".child").hide();
13
+ }
14
+
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,45 @@
1
+ # AnafHabtm
2
+
3
+ module ActiveRecordExtensions
4
+ def anaf_habtm(association, options={}, &block)
5
+ class_eval do
6
+ # Define a proc that will look up the (potentially) existing object
7
+ finder = proc {|id| association.to_s.singularize.camelize.constantize.where(:id=>id).first
8
+ }
9
+
10
+ # Define a proc that will set the association collection
11
+ set_collection = proc {|me, coll| me.send("#{association.to_s.tableize}=", coll)}
12
+ has_and_belongs_to_many association.to_sym, options
13
+ # Define the actual association setter.
14
+ define_method "#{association.to_s.tableize}_attributes=", lambda{|attributes_for_association|
15
+ coll = []
16
+
17
+ attributes_for_association.each_value do |params|
18
+ next if params["_destroy"] == "1"
19
+ obj = finder.call(params["id"]) if params.has_key?("id")
20
+ params.extend(HashExtension)
21
+ # ActiveRecord::Base.attributes=() doesn't like extra parameters.
22
+ coll << block.call(params.copy_without_destroy, obj)
23
+ end
24
+ set_collection.call(self, coll)
25
+ }
26
+ end
27
+ end
28
+
29
+ def named_association(member, klass, attribute, create=nil)
30
+ member = member.to_s
31
+ klass = klass.name
32
+ attribute = attribute.to_s
33
+ if create
34
+ class_eval "def #{member}_#{attribute}=(#{attribute});
35
+ return if #{attribute}.blank?
36
+ self.#{member} = #{klass}.find_or_create_by_#{attribute}(#{attribute})
37
+ end;"
38
+ else
39
+ class_eval "def #{member}_#{attribute}=(#{attribute}); self.#{member} = #{klass}.find_by_#{attribute}(#{attribute}) unless #{attribute}.blank?; end;"
40
+ end
41
+ class_eval "def #{member}_#{attribute}; #{member}.#{attribute} if #{member}; end;"
42
+ end
43
+
44
+
45
+ end
data/lib/anaf_habtm.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'hash'
2
+ require 'active_record_extensions'
3
+ require 'application_helper_methods'
4
+ ActiveRecord::Base.extend(ActiveRecordExtensions)
5
+ ActionView::Base.send :include, ApplicationHelperMethods
6
+
@@ -0,0 +1,20 @@
1
+ module ApplicationHelperMethods
2
+ def remove_child_link(name, form_builder)
3
+ form_builder.hidden_field(:_destroy) + link_to_function(name, "remove_child(this)", :tabindex => "0")
4
+ end
5
+
6
+ def add_child_link(name, child, form_builder)
7
+ # puts "||#{form_builder}||"
8
+ fields = escape_javascript(new_child_fields(child, form_builder))
9
+ link_to_function(name, h("add_child(this, \"#{child}\", \"#{fields}\")"))
10
+ end
11
+
12
+ def new_child_fields(child, form_builder)
13
+ output = ""
14
+ form_builder.fields_for(child.pluralize.to_sym, child.camelize.constantize.new, :child_index => 'NEW_RECORD') do |f|
15
+ output += render(:partial => child.underscore, :locals => { :f => f })
16
+ end
17
+ output
18
+ end
19
+ end
20
+
data/lib/hash.rb ADDED
@@ -0,0 +1,9 @@
1
+ module HashExtension
2
+ KEYS_TO_AVOID = ["_destroy", "id"]
3
+ def copy_without_destroy
4
+ a = {}
5
+ self.each {|key,val| a[key]=val unless KEYS_TO_AVOID.include?(key.to_s)}
6
+ a
7
+ end
8
+ end
9
+
@@ -0,0 +1,7 @@
1
+ namespace :anaf_habtm do
2
+ task :install do
3
+ cp 'vendor/plugins/anaf_habtm/assets/nested_attributes.js', 'public/javascripts'
4
+ end
5
+ end
6
+
7
+
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'anaf_habtm'
2
+
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class AnafHabtmTest < ActiveSupport::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'active_support'
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: anaf_habtm
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Tyler Gannon
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-09 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description:
23
+ email:
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - README
30
+ files:
31
+ - Gemfile
32
+ - MIT-LICENSE
33
+ - README
34
+ - Rakefile
35
+ - anaf_habtm.gemspec
36
+ - assets/nested_attributes.js
37
+ - install.rb
38
+ - lib/active_record_extensions.rb
39
+ - lib/anaf_habtm.rb
40
+ - lib/application_helper_methods.rb
41
+ - lib/hash.rb
42
+ - lib/tasks/install.rake
43
+ - rails/init.rb
44
+ - test/anaf_habtm_test.rb
45
+ - test/test_helper.rb
46
+ - uninstall.rb
47
+ has_rdoc: true
48
+ homepage: http://github.com/tylergannon/anaf_habtm
49
+ licenses: []
50
+
51
+ post_install_message:
52
+ rdoc_options:
53
+ - --charset=UTF-8
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ requirements: []
75
+
76
+ rubyforge_project:
77
+ rubygems_version: 1.3.7
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: accepts_nested_attributes_for habtm
81
+ test_files:
82
+ - test/anaf_habtm_test.rb
83
+ - test/test_helper.rb