carload 0.4.5 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 38d8d86c279079a2b6738899dc9719a2e390f7cf
4
- data.tar.gz: 2a1ba96d3612bffa65e66e86c54f8dae2e02baa8
3
+ metadata.gz: 189b67589521f80841e31c1d6b88faf83808fdcb
4
+ data.tar.gz: 48ba545a059e0dcd99778f25364dd3a406a9b5aa
5
5
  SHA512:
6
- metadata.gz: 662f9e8185472e55a3babe45e1eb00d17dd59d1b18132ea914d4e237a6b0997a407923373a41b66ab4a3a7e483b490da31216da7f2b150b718b558b3b5d3a648
7
- data.tar.gz: 25e7242afb48a2dff092174cdff5b3067fb366a9ea08deba67b7ed89a51b91d9f08026775c49d168f3a1f032f435bb3084bd0e6e432d247af2e568eb1bbb327e
6
+ metadata.gz: 768362151f2686fc48f7f5573f63e40b599bdbfc5bf2c6a3ef93268004c9702150c51ad9ce577498aacccd6f3e520c35b7bf6d0b81cb0139c4f52d14f1a00329
7
+ data.tar.gz: e4fa219c45c59ecda87d186cd3353cf5406ccf89f21c68885e0fa77c0890b25e0e5d41af809f1a7b1adf7fafe537dbb9fc45cb6eeb0519e9ea3b24056af22db5
@@ -9,8 +9,9 @@ module Carload
9
9
  end
10
10
 
11
11
  def polymorphic? attribute_name
12
- Dashboard.model(@model_name).associated_models.each_value do |associated_model|
13
- return associated_model[:name] if attribute_name =~ /#{associated_model[:name]}/ and associated_model[:polymorphic]
12
+ Dashboard.model(@model_name).associations.each_value do |association|
13
+ reflection = association[:reflection]
14
+ return reflection.name if attribute_name =~ /#{reflection.name}/ and reflection.options[:polymorphic]
14
15
  end
15
16
  false
16
17
  end
@@ -19,12 +20,20 @@ module Carload
19
20
  attribute_name.to_s =~ /image|logo|img/
20
21
  end
21
22
 
22
- def id_or_ids associated_model
23
- case associated_model[:association_type]
24
- when :has_many
25
- "#{associated_model[:name]}_ids"
23
+ def associated_model_name model_name, attribute_name
24
+ x = attribute_name.gsub(/_ids?$/, '').to_sym
25
+ Dashboard.model(model_name).associations.each do |name, association|
26
+ return association[:class_name] || x, name if name.to_s.singularize.to_sym == x
27
+ end
28
+ raise 'Should not go here!'
29
+ end
30
+
31
+ def id_or_ids reflection
32
+ case reflection
33
+ when ActiveRecord::Reflection::HasManyReflection
34
+ "#{reflection.name.to_s.singularize}_ids"
26
35
  else
27
- "#{associated_model[:name]}_id"
36
+ "#{reflection.name}_id"
28
37
  end
29
38
  end
30
39
  end
@@ -7,43 +7,32 @@ module Carload
7
7
  selected: options[:value],
8
8
  input_html: { class: 'use-select2' }
9
9
  elsif attribute_name =~ /_id$/
10
- associated_model = attribute_name.gsub(/_id$/, '').to_sym
11
- association_specs = Dashboard.model(model_name).associated_models[associated_model]
12
- label_attribute = association_specs[:choose_by]
13
- form.association associated_model,
10
+ class_name, association_name = associated_model_name model_name, attribute_name
11
+ association = Dashboard.model(model_name).associations[association_name]
12
+ label_attribute = association[:choose_by]
13
+ form.association association_name,
14
14
  label_method: label_attribute,
15
- label: t("activerecord.models.#{associated_model}"),
15
+ label: t("activerecord.models.#{class_name}"),
16
16
  input_html: {
17
17
  class: 'use-select2',
18
18
  data: {
19
- placeholder: t('carload.placeholder.select', thing: t("activerecord.attributes.#{associated_model}.#{label_attribute}"))
19
+ placeholder: t('carload.placeholder.select', thing: t("activerecord.attributes.#{class_name}.#{label_attribute}"))
20
20
  }
21
21
  }
22
22
  elsif attribute_name =~ /_ids$/
23
- # Mandle many-to-many association.
24
- associated_model = attribute_name.gsub(/_ids$/, '').to_sym
25
- association_specs = Dashboard.model(model_name).associated_models[associated_model]
26
- label_attribute = association_specs[:choose_by]
23
+ class_name, association_name = associated_model_name model_name, attribute_name
24
+ association = Dashboard.model(model_name).associations[association_name]
25
+ label_attribute = association[:choose_by]
27
26
  form.input attribute_name,
28
- label: t("activerecord.attributes.#{associated_model}.#{label_attribute}") + " (#{t("activerecord.models.#{associated_model}")})",
29
- collection: associated_model.to_s.camelize.constantize.all,
27
+ label: t("activerecord.attributes.#{class_name}.#{label_attribute}") + " (#{t("activerecord.models.#{class_name}")})",
28
+ collection: class_name.to_s.camelize.constantize.all,
30
29
  label_method: label_attribute,
31
30
  value_method: :id,
32
31
  input_html: {
33
32
  class: 'use-select2',
34
33
  multiple: true,
35
34
  data: {
36
- placeholder: t('carload.placeholder.select', thing: t("activerecord.attributes.#{associated_model}.#{label_attribute}"))
37
- }
38
- }
39
- elsif attribute_name =~ /_type$/
40
- associated_model = attribute_name.gsub(/_type$/, '').to_sym
41
- association_specs = Dashboard.model(model_name).associated_models[associated_model]
42
- form.input attribute_name, collection: association_specs[:instance_models].map{ |x| x.to_s.camelize },
43
- input_html: {
44
- class: 'use-select2',
45
- data: {
46
- placeholder: t('carload.placeholder.select', thing: t("activerecord.attributes.#{model_name}.#{attribute_name}"))
35
+ placeholder: t('carload.placeholder.select', thing: t("activerecord.attributes.#{class_name}.#{label_attribute}"))
47
36
  }
48
37
  }
49
38
  elsif needs_upload?(model_name, attribute_name) and image?(attribute_name)
@@ -99,7 +88,11 @@ module Carload
99
88
  raise UnsupportedError.new("attribute #{attribute}") if attribute.size != 3
100
89
  model_name = attribute[1].to_s.singularize
101
90
  attribute_name = attribute[2]
102
- "#{t("activerecord.attributes.#{model_name}.#{attribute_name}", raise: true)} (#{t("activerecord.models.#{model_name}", raise: true)})"
91
+ begin
92
+ "#{t("activerecord.attributes.#{model_name}.#{attribute_name}", raise: true)} (#{t("activerecord.models.#{model_name}", raise: true)})"
93
+ rescue
94
+ "#{t("activerecord.attributes.#{@model_name}.#{model_name}.#{attribute_name}", raise: true)}"
95
+ end
103
96
  else
104
97
  "#{t("activerecord.attributes.#{attribute.join('.')}", raise: true)} (#{t("activerecord.models.#{attribute[0].to_s.singularize}", raise: true)})"
105
98
  end
@@ -5,15 +5,17 @@
5
5
  <%= generate_input f, @model_name, name, type: column.type %>
6
6
  <% end %>
7
7
  <!-- Polymorphics -->
8
- <% Dashboard.model(@model_name).associated_models.each_value do |associated_model| %>
9
- <% next if associated_model[:polymorphic] != true %>
10
- <%= generate_input f, @model_name, associated_model[:name], polymorphic: true,
11
- value: "#{@object.send("#{associated_model[:name]}_id")},#{@object.send("#{associated_model[:name]}_type")}" %>
8
+ <% Dashboard.model(@model_name).associations.each_value do |association| %>
9
+ <% reflection = association[:reflection] %>
10
+ <% next unless reflection.options[:polymorphic] %>
11
+ <%= generate_input f, @model_name, reflection.name, polymorphic: true,
12
+ value: "#{@object.send("#{reflection.name}_id")},#{@object.send("#{reflection.name}_type")}" %>
12
13
  <% end %>
13
14
  <!-- Join tables -->
14
- <% Dashboard.model(@model_name).associated_models.each_value do |associated_model| %>
15
- <% next if not associated_model[:join_table] %>
16
- <%= generate_input f, @model_name, id_or_ids(associated_model) %>
15
+ <% Dashboard.model(@model_name).associations.each_value do |association| %>
16
+ <% reflection = association[:reflection] %>
17
+ <% next unless reflection.options[:through] %>
18
+ <%= generate_input f, @model_name, id_or_ids(reflection.delegate_reflection) %>
17
19
  <% end %>
18
20
  <%= f.button :submit, t('carload.action.submit'), class: 'btn btn-primary' %>
19
21
  <% end %>
data/lib/carload.rb CHANGED
@@ -9,7 +9,6 @@ Gem.loaded_specs['carload'].dependencies.each do |dependency|
9
9
  end
10
10
 
11
11
  require 'carload/extended_hash'
12
- require 'carload/association_pipelines'
13
12
  require 'carload/model_spec'
14
13
  require 'carload/dashboard'
15
14
  require 'carload/engine'
@@ -18,9 +18,7 @@ module Carload
18
18
  model_a = options.keys.first
19
19
  model_b = options.values.first
20
20
  options.shift
21
- options[:name] = model_b
22
- @@models[model_a] ||= ModelSpec.new
23
- @@models[model_a].associated_models[model_b] = options
21
+ @@models[model_a].associations[model_b] = options
24
22
  end
25
23
 
26
24
  def models
@@ -49,11 +47,12 @@ module Carload
49
47
  end
50
48
  RUBY
51
49
  default = false
52
- next if spec.associated_models.empty?
53
- spec.associated_models.each_value do |associated_model|
54
- next unless associated_model[:choose_by]
50
+ next if spec.associations.empty?
51
+ spec.associations.each_value do |association|
52
+ next unless association[:choose_by]
53
+ reflection = association[:reflection]
55
54
  content << <<-RUBY
56
- associate(#{{ name.to_sym => associated_model[:name], choose_by: associated_model[:choose_by].to_sym }})
55
+ associate(#{{ name.to_sym => reflection.name, choose_by: association[:choose_by] }})
57
56
  RUBY
58
57
  end
59
58
  end
@@ -13,9 +13,15 @@ module Carload
13
13
  # Fill up associations of models.
14
14
  Dashboard.models.each do |name, spec|
15
15
  spec.klass = name.to_s.camelize.constantize
16
- spec.klass.reflect_on_all_associations.each do |association|
17
- spec.handle_association association, rescue: true
16
+ spec.klass.reflect_on_all_associations.each do |reflection|
17
+ next unless spec.associations.has_key? reflection.name
18
+ spec.associations[reflection.name][:reflection] = reflection
19
+ # Record real class name.
20
+ if reflection.options.has_key? :class_name
21
+ spec.associations[reflection.name][:class_name] = reflection.options[:class_name].to_s.underscore.to_sym
22
+ end
18
23
  end
24
+ spec.process_associaitons
19
25
  end
20
26
  # Reopen model classes to add pg text search.
21
27
  case (Carload.search_engine rescue nil)
@@ -56,16 +62,16 @@ module Carload
56
62
  end
57
63
  # Reopen model classes to handle polymorphic association.
58
64
  Dashboard.models.each do |name, spec|
59
- spec.associated_models.values.select { |x| x[:polymorphic] == true }.each do |associated_model|
65
+ spec.associations.values.select { |x| x[:reflection].options[:polymorphic] }.each do |association|
60
66
  polymorphic_objects = []
61
- associated_model[:instance_models].each do |instance_model|
67
+ association[:instance_models].each do |instance_model|
62
68
  Dashboard.model(instance_model).klass.all.each do |object|
63
- polymorphic_objects << ["#{object.class} - #{object.send(associated_model[:choose_by])}", "#{object.id},#{object.class}"]
69
+ polymorphic_objects << ["#{object.class} - #{object.send(association[:choose_by])}", "#{object.id},#{object.class}"]
64
70
  end
65
71
  end
66
72
  spec.klass.class_eval do
67
73
  class_eval <<-RUBY
68
- def self.#{associated_model[:name].to_s.pluralize}
74
+ def self.#{association[:reflection].name.to_s.pluralize}
69
75
  #{polymorphic_objects}
70
76
  end
71
77
  RUBY
@@ -1,8 +1,6 @@
1
1
  module Carload
2
2
  class ModelSpec
3
- include AssociationPipelines
4
-
5
- attr_accessor :name, :klass, :default, :attributes, :index_page, :associated_models
3
+ attr_accessor :name, :klass, :default, :attributes, :index_page, :associations
6
4
 
7
5
  SkippedAttributes = [
8
6
  'id', 'created_at', 'updated_at',
@@ -13,13 +11,6 @@ module Carload
13
11
  'last_sign_in_ip'
14
12
  ].freeze
15
13
 
16
- AssociationTypes = {
17
- ActiveRecord::Reflection::BelongsToReflection => :belongs_to,
18
- ActiveRecord::Reflection::HasOneReflection => :has_one,
19
- ActiveRecord::Reflection::HasManyReflection => :has_many,
20
- ActiveRecord::Reflection::ThroughReflection => :through
21
- }
22
-
23
14
  def initialize model_class = nil
24
15
  @default = false
25
16
  @attributes = ExtendedHash.new
@@ -28,20 +19,55 @@ module Carload
28
19
  @index_page[:shows][:attributes] ||= []
29
20
  @index_page[:searches] = ExtendedHash.new
30
21
  @index_page[:searches][:attributes] ||= []
31
- @associated_models = {}
22
+ @associations ||= {}
32
23
  if model_class
33
24
  @name = model_class.name.underscore
34
25
  @klass = model_class
35
26
  @attributes[:permitted] = (model_class.column_names - SkippedAttributes).map(&:to_sym)
36
- # Handle model associations.
37
- model_class.reflect_on_all_associations.each do |association|
38
- handle_association association
39
- end
40
27
  @attributes[:permitted].each do |attribute|
41
28
  next if attribute.class == Hash
42
29
  @index_page[:shows][:attributes] << attribute
43
30
  @index_page[:searches][:attributes] << { name: attribute.to_sym, term: :cont }
44
31
  end
32
+ model_class.reflect_on_all_associations.each do |reflection|
33
+ @associations[reflection.name] = {
34
+ reflection: reflection,
35
+ choose_by: nil
36
+ }
37
+ end
38
+ process_associaitons
39
+ end
40
+ end
41
+
42
+ def process_associaitons
43
+ @associations.each_value do |association|
44
+ reflection = association[:reflection]
45
+ if join_table = reflection.options[:through] and @associations.has_key? join_table
46
+ # Filter join table.
47
+ @associations.select { |k, v| v[:reflection].name == join_table }.values.first[:filtered] = true
48
+ # Permit foreign id.
49
+ case reflection.delegate_reflection
50
+ when ActiveRecord::Reflection::HasOneReflection
51
+ @attributes[:permitted] << :"#{reflection.delegate_reflection.name}_id"
52
+ when ActiveRecord::Reflection::HasManyReflection
53
+ @attributes[:permitted] << { :"#{reflection.delegate_reflection.name.to_s.singularize}_ids" => [] }
54
+ end
55
+ elsif reflection.options[:polymorphic]
56
+ ActiveRecord::Base.descendants.each do |_model|
57
+ next if _model.name == 'ApplicationRecord' or _model.name.underscore == @name.to_s
58
+ _model.reflect_on_all_associations.each do |_reflection|
59
+ next unless _reflection.options[:as] == reflection.name
60
+ if association.has_key? :attributes
61
+ association[:attributes] = association[:attributes] & _model.column_names
62
+ else
63
+ association[:attributes] = _model.column_names - SkippedAttributes
64
+ end
65
+ association[:instance_models] ||= []
66
+ association[:instance_models] << _model.name.underscore.to_sym
67
+ end
68
+ end
69
+ association[:attributes] = association[:attributes].map(&:to_sym)
70
+ end
45
71
  end
46
72
  end
47
73
 
@@ -51,48 +77,5 @@ module Carload
51
77
  not @index_page[:shows][:attributes] == spec.index_page[:shows][:attributes] or
52
78
  not @index_page[:searches][:attributes] == spec.index_page[:searches][:attributes]
53
79
  end
54
-
55
- def revise!
56
- # Handle associated models if necessary.
57
- @associated_models.each_value do |associated_model|
58
- next unless associated_model[:choose_by]
59
- if associated_model[:association_type] == :has_many
60
- show_name = [:pluck, associated_model[:name].to_s.pluralize.to_sym, associated_model[:choose_by]]
61
- else
62
- show_name = "#{associated_model[:name]}.#{associated_model[:choose_by]}"
63
- end
64
- @index_page[:shows][:attributes].delete_if { |x| x == :"#{associated_model[:name]}_id" }
65
- @index_page[:shows][:attributes] << show_name
66
- end
67
- end
68
-
69
- def handle_association association, options = {}
70
- begin
71
- _association = (association.delegate_reflection rescue nil) || association
72
- name = (_association.klass.name.underscore.to_sym rescue nil) || _association.name
73
- association_type = AssociationTypes[_association.class]
74
- polymorphic = association.options[:polymorphic] || association.options[:as]
75
- foreign_key = @klass.column_names.include?("#{(_association.klass.name.underscore rescue nil) || _association.name}_id")
76
- join_table = association.options[:through].to_s.singularize.to_sym if association.options[:through]
77
- @associated_models[name] = {
78
- name: name,
79
- association_type: association_type,
80
- polymorphic: polymorphic,
81
- foreign_key: foreign_key,
82
- join_table: join_table,
83
- choose_by: nil
84
- }.merge @associated_models[name] || {}
85
- association_pipelines.each { |pipeline| send pipeline, association }
86
- # Delete join-table model!
87
- if association.options[:through]
88
- @associated_models.delete association.options[:through]
89
- @associated_models.delete association.options[:through].to_s.singularize.to_sym
90
- end
91
- rescue => e
92
- raise e unless options[:rescue]
93
- raise e if not e&.original_exception&.class == PG::UndefinedTable and
94
- not e.class == ActiveRecord::NoDatabaseError
95
- end
96
- end
97
80
  end
98
81
  end
@@ -1,3 +1,3 @@
1
1
  module Carload
2
- VERSION = '0.4.5'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -3,42 +3,53 @@ module Carload
3
3
  source_root File.expand_path('../templates', __FILE__)
4
4
 
5
5
  def change_dashboard_file
6
+ # It is necessary to load models manually.
7
+ Rails.application.eager_load!
6
8
  # Process model once atime.
7
- model = file_name
8
9
  model_specs = {}
9
- Rails.application.eager_load! # It is necessary to load models manually.
10
10
  ActiveRecord::Base.descendants.each do |model| # Rails 5 can use ApplicationRecord.
11
11
  next if model.name == 'ApplicationRecord' or model.name == 'PgSearch::Document'
12
- name = model.name.underscore
13
- model_specs[name] = ModelSpec.new model
12
+ model_specs[model.name.underscore.to_sym] = ModelSpec.new model
14
13
  end
15
- spec = model_specs[model]
16
- if not spec.associated_models.empty?
14
+ model_name = file_name.to_sym
15
+ spec = model_specs[model_name]
16
+ if not spec.associations.empty?
17
17
  cli = HighLine.new
18
- spec.associated_models.each_value do |associated_model|
19
- next if associated_model[:attributes].empty?
20
- if associated_model[:polymorphic]
21
- attributes = associated_model[:attributes]
18
+ spec.associations.each do |name, association|
19
+ next if association[:filtered]
20
+ reflection = association[:reflection]
21
+ next if reflection.class ==
22
+ if reflection.options[:polymorphic]
23
+ attributes = association[:attributes]
24
+ elsif reflection.options[:class_name]
25
+ attributes = model_specs[reflection.options[:class_name].underscore.to_sym].attributes.permitted.select { |x| x.class != Hash }
22
26
  else
23
- attributes = model_specs[associated_model[:name].to_s].attributes.permitted.select { |x| x.class != Hash }
27
+ attributes = model_specs[reflection.name.to_s.singularize.to_sym].attributes.permitted.select { |x| x.class != Hash }
24
28
  end
25
29
  if attributes.size == 1
26
- associated_model[:choose_by] = attributes.first
30
+ association[:choose_by] = attributes.first
27
31
  else
28
- associated_model[:choose_by] = cli.choose do |menu|
29
- menu.prompt = "Choose the attribute of model #{associated_model[:name]} for choosing in #{model}? "
32
+ association[:choose_by] = cli.choose do |menu|
33
+ menu.prompt = "Choose the attribute of model #{reflection.name} for choosing in #{model_name}? "
30
34
  attributes.each do |attribute|
31
35
  next if attribute.to_s =~ /_id$/
32
36
  menu.choice attribute
33
37
  end
34
38
  end
35
39
  end
40
+ # Change corresponding show attribute.
41
+ spec.index_page[:shows][:attributes] = spec.index_page[:shows][:attributes].map do |attribute|
42
+ if attribute.to_s =~ /#{name}/
43
+ attribute = "#{name}.#{association[:choose_by]}"
44
+ else
45
+ attribute
46
+ end
47
+ end
36
48
  end
37
- spec.revise!
38
49
  end
39
50
  # Check if model exists in dashboard file, but it may be changed.
40
- if not Dashboard.models.keys.include? model.to_sym or Dashboard.model(model).changed? spec
41
- Dashboard.models[model.to_sym] = spec
51
+ if not Dashboard.models.keys.include? model_name or Dashboard.model(model_name).changed? spec
52
+ Dashboard.models[model_name] = spec
42
53
  Dashboard.write 'app/carload/dashboard.rb'
43
54
  end
44
55
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carload
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Li Dong
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-09 00:00:00.000000000 Z
11
+ date: 2016-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -296,7 +296,6 @@ files:
296
296
  - config/routes.rb
297
297
  - db/migrate/20161030074822_carload_enable_zhparser_extension.rb
298
298
  - lib/carload.rb
299
- - lib/carload/association_pipelines.rb
300
299
  - lib/carload/dashboard.rb
301
300
  - lib/carload/engine.rb
302
301
  - lib/carload/exceptions.rb
@@ -1,52 +0,0 @@
1
- module Carload
2
- module AssociationPipelines
3
- def association_pipelines
4
- [ :pipeline_1, :pipeline_2, :pipeline_3 ]
5
- end
6
-
7
- # Find polymorphic instance models.
8
- def pipeline_1 association
9
- return unless association.options[:polymorphic]
10
- associated_model = @associated_models[association.name]
11
- ActiveRecord::Base.descendants.each do |model|
12
- next if model.name == 'ApplicationRecord' or model.name.underscore == @name.to_s
13
- model.reflect_on_all_associations.each do |model_association|
14
- next unless model_association.options[:as] == association.name
15
- associated_model[:instance_models] ||= []
16
- associated_model[:instance_models] << model.name.underscore.to_sym
17
- if not associated_model[:attributes]
18
- associated_model[:attributes] = model.column_names - ModelSpec::SkippedAttributes
19
- else
20
- associated_model[:attributes] = associated_model[:attributes] & model.column_names
21
- end
22
- end
23
- end
24
- end
25
-
26
- # Add possible attributes to let user choose.
27
- def pipeline_2 association
28
- return unless associated_model = @associated_models[association.name.to_s.singularize.to_sym]
29
- model = association.name.to_s.singularize.camelize.constantize rescue return
30
- associated_model[:attributes] ||= []
31
- associated_model[:attributes] = model.column_names - ModelSpec::SkippedAttributes
32
- associated_model[:attributes] = associated_model[:attributes] - [
33
- "#{@name}_id",
34
- "#{associated_model[:polymorphic]}_id",
35
- "#{associated_model[:polymorphic]}_type"
36
- ]
37
- end
38
-
39
- # Add has-many permitted attribute.
40
- def pipeline_3 association
41
- _association = (association.delegate_reflection rescue nil) || association
42
- return unless _association.class == ActiveRecord::Reflection::HasManyReflection
43
- # Exclude join table.
44
- return unless @klass.reflect_on_all_associations.select { |x| x.options[:through] == _association.name }.empty?
45
- @attributes[:permitted].each do |permitted|
46
- next unless permitted.class == Hash
47
- return if permitted.keys.first == :"#{_association.class_name.underscore}_ids"
48
- end
49
- @attributes[:permitted] << { :"#{_association.class_name.underscore}_ids" => [] }
50
- end
51
- end
52
- end