aa_associations 0.1.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.
- data/.gitignore +53 -0
- data/Gemfile +10 -0
- data/MIT_LICENSE.txt +20 -0
- data/README.md +213 -0
- data/Rakefile +17 -0
- data/aa_associations.gemspec +31 -0
- data/app/controllers/autocomplete_controller.rb +37 -0
- data/app/helpers/active_admin_associations_helper.rb +77 -0
- data/app/views/admin/shared/_add_to_association.html.erb +21 -0
- data/app/views/admin/shared/_association_collection_table_actions.html.erb +4 -0
- data/app/views/admin/shared/_blank_slate.html.erb +3 -0
- data/app/views/admin/shared/_collection_table.html.erb +58 -0
- data/app/views/admin/shared/_form.html.erb +7 -0
- data/config/routes.rb +7 -0
- data/lib/aa_associations.rb +20 -0
- data/lib/active_admin_associations/active_admin_extensions.rb +13 -0
- data/lib/active_admin_associations/association_actions.rb +43 -0
- data/lib/active_admin_associations/association_config.rb +50 -0
- data/lib/active_admin_associations/autocompleter.rb +64 -0
- data/lib/active_admin_associations/engine.rb +25 -0
- data/lib/active_admin_associations/form_config_dsl.rb +15 -0
- data/lib/active_admin_associations/redirect_destroy_actions.rb +7 -0
- data/lib/active_admin_associations/version.rb +3 -0
- data/lib/formtastic/inputs/token_input.rb +43 -0
- data/lib/formtastic/token_input_default_for_association.rb +19 -0
- data/test/active_admin_associations_test.rb +69 -0
- data/test/admin_posts_controller_test.rb +52 -0
- data/test/association_config_test.rb +43 -0
- data/test/autocomplete_controller_test.rb +27 -0
- data/test/autocompleter_test.rb +62 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/admin/dashboards.rb +44 -0
- data/test/dummy/app/admin/posts.rb +20 -0
- data/test/dummy/app/admin/tags.rb +11 -0
- data/test/dummy/app/assets/javascripts/active_admin.js +8 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/active_admin.css.scss +6 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/mailers/.gitkeep +0 -0
- data/test/dummy/app/models/.gitkeep +0 -0
- data/test/dummy/app/models/admin_user.rb +10 -0
- data/test/dummy/app/models/post.rb +11 -0
- data/test/dummy/app/models/tag.rb +15 -0
- data/test/dummy/app/models/tagging.rb +7 -0
- data/test/dummy/app/models/user.rb +8 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +63 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +19 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/active_admin.rb +129 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/devise.rb +216 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/devise.en.yml +57 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +62 -0
- data/test/dummy/db/.gitignore +1 -0
- data/test/dummy/db/migrate/20120504220404_devise_create_admin_users.rb +52 -0
- data/test/dummy/db/migrate/20120504221534_create_posts.rb +12 -0
- data/test/dummy/db/migrate/20120504221936_create_users.rb +9 -0
- data/test/dummy/db/migrate/20120504222040_create_tags.rb +8 -0
- data/test/dummy/db/migrate/20120504222247_create_taggings.rb +10 -0
- data/test/dummy/db/schema.rb +65 -0
- data/test/dummy/lib/assets/.gitkeep +0 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/factories/admin_users.rb +9 -0
- data/test/dummy/test/factories/posts.rb +11 -0
- data/test/dummy/test/factories/taggings.rb +6 -0
- data/test/dummy/test/factories/tags.rb +7 -0
- data/test/dummy/test/factories/users.rb +8 -0
- data/test/dummy/test/unit/admin_user_test.rb +7 -0
- data/test/dummy/test/unit/post_test.rb +7 -0
- data/test/dummy/test/unit/tag_test.rb +7 -0
- data/test/dummy/test/unit/tagging_test.rb +7 -0
- data/test/dummy/test/unit/user_test.rb +7 -0
- data/test/support/should_change.rb +29 -0
- data/test/test_helper.rb +51 -0
- data/vendor/assets/javascripts/active_admin_associations.js +14 -0
- data/vendor/assets/javascripts/jquery.tokeninput.js +915 -0
- data/vendor/assets/stylesheets/active_admin_associations.css.scss +18 -0
- data/vendor/assets/stylesheets/token-input-facebook.css +121 -0
- metadata +362 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<%- if resource_administrated?(relationship_class) && relationship_class.respond_to?(:autocomplete_attribute) && relationship_class.autocomplete_attribute.present? -%>
|
|
2
|
+
<%= form_tag relate_to_url(object), :class => 'relate-to-form', :method => :put do %>
|
|
3
|
+
<fieldset class="inputs">
|
|
4
|
+
<h4>Add a <%= relationship_class.model_name.human %></h4>
|
|
5
|
+
<%= hidden_field_tag 'relationship_name', relationship %>
|
|
6
|
+
<ol>
|
|
7
|
+
<li class="label">
|
|
8
|
+
<label for="related_id">
|
|
9
|
+
<%= relationship_class.model_name.human %>
|
|
10
|
+
<%= relationship_class.human_attribute_name(relationship_class.autocomplete_attribute) %>
|
|
11
|
+
</label>
|
|
12
|
+
</li>
|
|
13
|
+
<li class="input">
|
|
14
|
+
<%= hidden_field_tag 'related_id', nil, :class => 'token-input',
|
|
15
|
+
'data-model-name' => relationship_class.model_name.singular %>
|
|
16
|
+
</li>
|
|
17
|
+
<li class="button"><%= submit_tag "Add #{relationship_class.model_name.human}" %></li>
|
|
18
|
+
</ol>
|
|
19
|
+
</fieldset>
|
|
20
|
+
<% end %>
|
|
21
|
+
<%- end -%>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<div class="relationship-table" id="relationship-table-<%= relationship %>">
|
|
2
|
+
<h3><%= object.class.human_attribute_name(relationship) %></h3>
|
|
3
|
+
<%= render :partial => 'admin/shared/add_to_association', :locals => {
|
|
4
|
+
:relationship_class => relationship_class,
|
|
5
|
+
:object => object,
|
|
6
|
+
:relationship => relationship
|
|
7
|
+
} %>
|
|
8
|
+
<%- if collection.present? -%>
|
|
9
|
+
<table class="index_table">
|
|
10
|
+
<thead>
|
|
11
|
+
<tr>
|
|
12
|
+
<th>ID</th>
|
|
13
|
+
<% columns.each do |column| %>
|
|
14
|
+
<th><%= relationship_class.human_attribute_name(column) %></th>
|
|
15
|
+
<%- end -%>
|
|
16
|
+
<th> </th>
|
|
17
|
+
</tr>
|
|
18
|
+
</thead>
|
|
19
|
+
<tbody>
|
|
20
|
+
<%- collection.each do |record| -%>
|
|
21
|
+
<tr class="<%= cycle("odd", "even") -%>">
|
|
22
|
+
<td><%= record.id %></td>
|
|
23
|
+
<%- columns.each do |column| -%>
|
|
24
|
+
<%- if record.send(column).is_a?(ActiveRecord::Base) -%>
|
|
25
|
+
<td><%= display_name_for(record.send(column)) %></td>
|
|
26
|
+
<%- else -%>
|
|
27
|
+
<td><%= record.send(column) %></td>
|
|
28
|
+
<%- end -%>
|
|
29
|
+
<%- end -%>
|
|
30
|
+
<td class="actions">
|
|
31
|
+
<%- if resource_administrated?(record.class) -%>
|
|
32
|
+
<%= render :partial => 'admin/shared/association_collection_table_actions', :locals => {
|
|
33
|
+
:record => record,
|
|
34
|
+
:object => object,
|
|
35
|
+
:relationship => relationship
|
|
36
|
+
} %>
|
|
37
|
+
<%- else -%>
|
|
38
|
+
|
|
39
|
+
<%- end -%>
|
|
40
|
+
</td>
|
|
41
|
+
</tr>
|
|
42
|
+
<%- end -%>
|
|
43
|
+
</tbody>
|
|
44
|
+
</table>
|
|
45
|
+
<div class="resource-table-footer">
|
|
46
|
+
<%= paginate collection, :remote => true, :params => {
|
|
47
|
+
:action => 'page_related', :relationship_name => relationship
|
|
48
|
+
} %>
|
|
49
|
+
<div class="pagination_information">
|
|
50
|
+
<%= raw page_entries_info(collection) %>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
<%- else -%>
|
|
54
|
+
<%= render :partial => 'admin/shared/blank_slate', :locals => {
|
|
55
|
+
:blank_text => "There are no #{object.class.human_attribute_name(relationship)}"
|
|
56
|
+
} %>
|
|
57
|
+
<%- end -%>
|
|
58
|
+
</div>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<%= admin_form_for resource %>
|
|
2
|
+
|
|
3
|
+
<%- if resource.persisted? && active_admin_config.form_associations.present? -%>
|
|
4
|
+
<%- active_admin_config.form_associations.each do |association| -%>
|
|
5
|
+
<%= collection_relationship_manager(resource, association) %>
|
|
6
|
+
<%- end -%>
|
|
7
|
+
<%- end -%>
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
if Rails.application.config.aa_associations.autocomplete_models
|
|
2
|
+
models = Rails.application.config.aa_associations.autocomplete_models.join('|')
|
|
3
|
+
Rails.application.routes.draw do
|
|
4
|
+
match '/autocomplete/:model' => 'autocomplete#index', :model => /(#{models})/,
|
|
5
|
+
:defaults => { :format => 'json' }
|
|
6
|
+
end
|
|
7
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'active_support'
|
|
2
|
+
require 'activeadmin'
|
|
3
|
+
require 'active_admin_associations/version'
|
|
4
|
+
require 'active_admin_associations/active_admin_extensions'
|
|
5
|
+
require 'formtastic/token_input_default_for_association'
|
|
6
|
+
require 'formtastic/inputs/token_input'
|
|
7
|
+
|
|
8
|
+
module ActiveAdminAssociations
|
|
9
|
+
extend ActiveSupport::Autoload
|
|
10
|
+
|
|
11
|
+
eager_autoload do
|
|
12
|
+
autoload :AssociationActions
|
|
13
|
+
autoload :FormConfigDSL
|
|
14
|
+
autoload :RedirectDestroyActions
|
|
15
|
+
autoload :Autocompleter
|
|
16
|
+
autoload :AssociationConfig
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
require 'active_admin_associations/engine'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module ActiveAdmin
|
|
2
|
+
class Resource
|
|
3
|
+
attr_accessor :form_columns
|
|
4
|
+
attr_accessor :form_associations
|
|
5
|
+
attr_accessor :active_association_form
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
def resources
|
|
10
|
+
application.namespaces.values.map{|n| n.resources.resources }.flatten.compact.map(&:resource_class)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module ActiveAdminAssociations
|
|
2
|
+
module AssociationActions
|
|
3
|
+
def association_actions
|
|
4
|
+
member_action :unrelate, :method => :put do
|
|
5
|
+
reflection = resource_class.reflect_on_association(params[:relationship_name].to_sym)
|
|
6
|
+
if reflection.collection?
|
|
7
|
+
related_record = reflection.klass.find(params[:related_id])
|
|
8
|
+
resource.send(params[:relationship_name]).delete(related_record)
|
|
9
|
+
else
|
|
10
|
+
resource.update_attribute("#{params[:relationship_name]}_id", nil)
|
|
11
|
+
end
|
|
12
|
+
flash[:notice] = "The recored has been unrelated."
|
|
13
|
+
redirect_to request.headers["Referer"].presence || admin_dashboard_url
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
member_action :relate, :method => :put do
|
|
17
|
+
reflection = resource_class.reflect_on_association(params[:relationship_name].to_sym)
|
|
18
|
+
if reflection.collection?
|
|
19
|
+
record_to_relate = reflection.klass.find(params[:related_id])
|
|
20
|
+
resource.send(params[:relationship_name]) << record_to_relate
|
|
21
|
+
else
|
|
22
|
+
resource.update_attribute("#{params[:relationship_name]}_id", record_to_relate)
|
|
23
|
+
end
|
|
24
|
+
flash[:notice] = "The recored has been related."
|
|
25
|
+
redirect_to request.headers["Referer"].presence || admin_dashboard_url
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
member_action :page_related, :method => :get do
|
|
29
|
+
relationship_name = params[:relationship_name].to_sym
|
|
30
|
+
association_config = active_admin_config.form_associations[relationship_name]
|
|
31
|
+
relationship_class = resource_class.reflect_on_association(relationship_name).klass
|
|
32
|
+
association_columns = association_config.fields.presence || relationship_class.content_columns
|
|
33
|
+
render :partial => 'admin/shared/collection_table', :locals => {
|
|
34
|
+
:object => resource,
|
|
35
|
+
:collection => resource.send(relationship_name).page(params[:page]),
|
|
36
|
+
:relationship => relationship_name,
|
|
37
|
+
:columns => association_columns,
|
|
38
|
+
:relationship_class => relationship_class
|
|
39
|
+
}
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module ActiveAdminAssociations
|
|
2
|
+
class AssociationConfig
|
|
3
|
+
include Enumerable
|
|
4
|
+
|
|
5
|
+
class Association
|
|
6
|
+
attr_reader :name
|
|
7
|
+
attr_reader :fields
|
|
8
|
+
|
|
9
|
+
def initialize(name, fields = [], &block)
|
|
10
|
+
@name = name.to_sym
|
|
11
|
+
@fields = fields
|
|
12
|
+
instance_exec(&block) if block_given?
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def field(name)
|
|
16
|
+
@fields << name
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def fields(*names)
|
|
20
|
+
@fields += names
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
attr_reader :association_configs
|
|
25
|
+
delegate :each, :to => :association_configs
|
|
26
|
+
|
|
27
|
+
def initialize(&block)
|
|
28
|
+
@association_configs = []
|
|
29
|
+
instance_exec(&block)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def blank?
|
|
33
|
+
@association_configs.blank?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def [](association_name)
|
|
37
|
+
@association_configs.detect {|a| a.name == association_name.to_sym }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def association(name, fields = [], &block)
|
|
41
|
+
@association_configs << Association.new(name, fields, &block)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def associations(*names)
|
|
45
|
+
names.each do |name|
|
|
46
|
+
@association_configs << Association.new(name)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module ActiveAdminAssociations
|
|
2
|
+
module Autocompleter
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
module ClassMethods
|
|
6
|
+
def autocomplete(attribute, options = {})
|
|
7
|
+
class_attribute :autocomplete_attribute
|
|
8
|
+
class_attribute :autocomplete_options
|
|
9
|
+
|
|
10
|
+
self.autocomplete_attribute = attribute
|
|
11
|
+
self.autocomplete_options = options
|
|
12
|
+
|
|
13
|
+
extend AutocompleteMethods
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
module AutocompleteMethods
|
|
18
|
+
def autocomplete_results(query)
|
|
19
|
+
results = where("LOWER(#{table_name}.#{autocomplete_attribute}) LIKE ?", "#{query.downcase}%").
|
|
20
|
+
order("#{table_name}.#{autocomplete_attribute} ASC")
|
|
21
|
+
results.map do |record|
|
|
22
|
+
_autocomplete_format_result(record)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def _autocomplete_format_result(record)
|
|
29
|
+
if configured_autocomplete_result_formatter?
|
|
30
|
+
aa_associations_config.autocomplete_result_formatter.call(record,
|
|
31
|
+
autocomplete_attribute, autocomplete_options)
|
|
32
|
+
else
|
|
33
|
+
label = _format_autocomplete_label(record)
|
|
34
|
+
{"label" => label, # This plays nice with both jQuery UI autocomplete and jquery.tokeninput
|
|
35
|
+
"value" => record.send(autocomplete_attribute),
|
|
36
|
+
"id" => record.id}
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def _format_autocomplete_label(record)
|
|
41
|
+
if autocomplete_options[:format_label].present?
|
|
42
|
+
if autocomplete_options[:format_label].is_a?(Symbol)
|
|
43
|
+
record.send(autocomplete_options[:format_label])
|
|
44
|
+
elsif autocomplete_options[:format_label].respond_to?(:call)
|
|
45
|
+
autocomplete_options[:format_label].call(record)
|
|
46
|
+
else
|
|
47
|
+
record.send(autocomplete_attribute)
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
record.send(autocomplete_attribute)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def configured_autocomplete_result_formatter?
|
|
55
|
+
aa_associations_config.autocomplete_result_formatter.present? &&
|
|
56
|
+
aa_associations_config.autocomplete_result_formatter.respond_to?(:call)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def aa_associations_config
|
|
60
|
+
Rails.application.config.aa_associations
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module ActiveAdminAssociations
|
|
2
|
+
class Engine < Rails::Engine
|
|
3
|
+
config.aa_associations = ActiveSupport::OrderedOptions.new
|
|
4
|
+
|
|
5
|
+
initializer "active_admin_associations.load_extensions" do |app|
|
|
6
|
+
ActiveAdmin::BaseController.helper ActiveAdminAssociationsHelper
|
|
7
|
+
ActiveAdmin::ResourceDSL.send(:include, ActiveAdminAssociations::AssociationActions)
|
|
8
|
+
ActiveAdmin::ResourceDSL.send(:include, ActiveAdminAssociations::FormConfigDSL)
|
|
9
|
+
|
|
10
|
+
unless app.config.aa_associations.destroy_redirect == false
|
|
11
|
+
ActiveAdmin::BaseController.send(:include, ActiveAdminAssociations::RedirectDestroyActions)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
unless app.config.aa_associations.autocomplete == false
|
|
15
|
+
ActiveSupport.on_load(:active_record) do
|
|
16
|
+
ActiveRecord::Base.send(:include, ActiveAdminAssociations::Autocompleter)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
Formtastic::Helpers::InputHelper.send(:include, Formtastic::TokenInputDefaultForAssociation)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
ActiveAdmin.application.register_stylesheet 'active_admin_associations'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module ActiveAdminAssociations
|
|
2
|
+
module FormConfigDSL
|
|
3
|
+
def active_association_form(&block)
|
|
4
|
+
config.active_association_form = block
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def form_columns(*column_names)
|
|
8
|
+
config.form_columns = column_names.flatten
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def form_associations(&block)
|
|
12
|
+
config.form_associations = AssociationConfig.new(&block)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module Inputs
|
|
3
|
+
class TokenInput
|
|
4
|
+
include Base
|
|
5
|
+
|
|
6
|
+
def to_html
|
|
7
|
+
input_wrapping do
|
|
8
|
+
label_html <<
|
|
9
|
+
builder.hidden_field(input_name, input_html_options)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def input_html_options
|
|
14
|
+
super.merge({
|
|
15
|
+
:required => nil,
|
|
16
|
+
:autofocus => nil,
|
|
17
|
+
:class => 'token-input',
|
|
18
|
+
'data-model-name' => reflection.klass.model_name.singular
|
|
19
|
+
}).tap do |html_options|
|
|
20
|
+
if record.present?
|
|
21
|
+
html_options["data-pre"] = prepopulated_value.to_json
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def prepopulated_value
|
|
27
|
+
[{"value" => name_value, "id" => record.id}]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def name_method
|
|
31
|
+
builder.collection_label_methods.find { |m| record.respond_to?(m) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def name_value
|
|
35
|
+
record.send(name_method)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def record
|
|
39
|
+
@object.send(method)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Formtastic
|
|
2
|
+
module TokenInputDefaultForAssociation
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
alias_method_chain :default_input_type, :token_default_for_association
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def default_input_type_with_token_default_for_association(method, options = {})
|
|
10
|
+
if @object
|
|
11
|
+
reflection = reflection_for(method)
|
|
12
|
+
if reflection && reflection.klass.respond_to?(:autocomplete_attribute) && reflection.macro == :belongs_to
|
|
13
|
+
return :token
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
default_input_type_without_token_default_for_association(method, options)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class ActiveAdminAssociationsTest < ActionDispatch::IntegrationTest
|
|
4
|
+
setup do
|
|
5
|
+
admin_login_as
|
|
6
|
+
@post = Factory(:post)
|
|
7
|
+
@tag = Factory(:tag)
|
|
8
|
+
@post.tags = [@tag]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
context 'editing a post' do
|
|
12
|
+
setup do
|
|
13
|
+
visit "/admin/posts/#{@post.id}/edit"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
should 'have correct inputs from form_columns config' do
|
|
17
|
+
assert page.has_selector?('form.post fieldset.inputs input#post_title'), 'no input for Post title'
|
|
18
|
+
assert page.has_selector?('form.post fieldset.inputs textarea#post_body'), 'no input for Post body'
|
|
19
|
+
assert page.has_selector?('form.post fieldset.inputs input#post_creator_id'), 'no input for Post creator'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
should 'have correct inputs from active_association_form config' do
|
|
23
|
+
assert page.has_selector?('form.post fieldset#more-inputs input.my-date-picker#post_published_at'), 'no input for Post published_at'
|
|
24
|
+
assert page.has_selector?('form.post fieldset#more-inputs input#post_featured'), 'no input for Post featured'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
should 'have correct token input for post creator' do
|
|
28
|
+
token_input = page.find('form.post fieldset.inputs input.token-input#post_creator_id')
|
|
29
|
+
assert_equal 'hidden', token_input["type"]
|
|
30
|
+
assert_equal 'user', token_input['data-model-name']
|
|
31
|
+
assert_equal '1', token_input['value']
|
|
32
|
+
assert_equal [{"value" => "Bill Tester", "id" => @post.creator_id}], MultiJson.decode(token_input['data-pre'])
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
should 'have a form to relate new tags' do
|
|
36
|
+
assert page.has_selector?('.relationship-table#relationship-table-tags form.relate-to-form')
|
|
37
|
+
assert page.has_selector?('#relationship-table-tags form.relate-to-form input[type="hidden"]#relationship_name')
|
|
38
|
+
assert_equal 'tags', page.find('#relationship-table-tags form.relate-to-form input#relationship_name')['value']
|
|
39
|
+
token_input = page.find('#relationship-table-tags form.relate-to-form input.token-input#related_id')
|
|
40
|
+
assert_equal 'tag', token_input['data-model-name']
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
should 'have a table of the related tags' do
|
|
44
|
+
assert page.has_xpath?('//div[@id="relationship-table-tags"]//table[@class="index_table"]/thead//th[text()="Name"]')
|
|
45
|
+
assert_equal @tag.name, page.find(:xpath, "//div[@id='relationship-table-tags']//table[@class='index_table']/tbody//tr[td[1][text()=#{@tag.id}]]//td[2]").text
|
|
46
|
+
edit_link = page.find(:xpath, "//div[@id='relationship-table-tags']//table[@class='index_table']/tbody//tr/td[3]/a[text()='Edit']")
|
|
47
|
+
assert_match %r{\A/admin/tags/\d+/edit}, edit_link['href']
|
|
48
|
+
|
|
49
|
+
assert page.has_xpath?("//div[@id='relationship-table-tags']//table[@class='index_table']/tbody//tr/td[3]/form//input[@type='submit'][@value='Unrelate']")
|
|
50
|
+
unrelate_form = page.find(:xpath, "//div[@id='relationship-table-tags']//table[@class='index_table']/tbody//tr/td[3]/form[@class='button_to']")
|
|
51
|
+
unrelate_url = unrelate_form['action']
|
|
52
|
+
assert_match %r{\A/admin/posts/#{@post.id}/unrelate}, unrelate_url
|
|
53
|
+
query_params = unrelate_url.split('?')[1].split('&')
|
|
54
|
+
assert_same_elements ["related_id=#{@tag.id}", 'relationship_name=tags'], query_params
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'editing a tag' do
|
|
59
|
+
setup do
|
|
60
|
+
visit "/admin/tags/#{@tag.id}/edit"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
should 'have a table of the related posts' do
|
|
64
|
+
assert page.has_xpath?('//div[@id="relationship-table-posts"]//table[@class="index_table"]/thead//th[text()="Title"]')
|
|
65
|
+
assert_equal @post.title, page.find(:xpath, "//div[@id='relationship-table-posts']//table[@class='index_table']/tbody//tr[td[1][text()=#{@post.id}]]//td[2]").text
|
|
66
|
+
assert_equal @post.creator.name, page.find(:xpath, "//div[@id='relationship-table-posts']//table[@class='index_table']/tbody//tr[td[1][text()=#{@post.id}]]//td[3]").text
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|