nocms-blocks 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG +8 -0
  3. data/LICENSE +674 -0
  4. data/README.md +233 -0
  5. data/Rakefile +22 -0
  6. data/app/assets/javascripts/no_cms/blocks/application.js +13 -0
  7. data/app/assets/stylesheets/no_cms/blocks/application.css +13 -0
  8. data/app/controllers/no_cms/blocks/application_controller.rb +4 -0
  9. data/app/decorators/models/no_cms/blocks/block_decorator.rb +3 -0
  10. data/app/helpers/no_cms/blocks/application_helper.rb +4 -0
  11. data/app/helpers/no_cms/blocks/blocks_helper.rb +28 -0
  12. data/app/models/no_cms/blocks/block.rb +160 -0
  13. data/app/models/no_cms/blocks/concerns/translation_scopes.rb +16 -0
  14. data/app/views/layouts/no_cms/blocks/application.html.erb +14 -0
  15. data/app/views/no_cms/admin/blocks/blocks/_default.html.erb +9 -0
  16. data/app/views/no_cms/admin/blocks/blocks/_form.html.erb +25 -0
  17. data/app/views/no_cms/admin/blocks/blocks/_index.html.erb +15 -0
  18. data/app/views/no_cms/admin/blocks/blocks/_nested_index.html.erb +17 -0
  19. data/app/views/no_cms/blocks/blocks/_default.html.erb +8 -0
  20. data/config/locales/en.yml +15 -0
  21. data/config/routes.rb +2 -0
  22. data/db/migrate/20140405135410_create_no_cms_blocks_blocks.rb +21 -0
  23. data/db/migrate/20140405150944_add_awesome_nested_set_to_no_cms_blocks.rb +8 -0
  24. data/db/migrate/20140618150651_add_position_to_no_cms_blocks_block.rb +5 -0
  25. data/lib/generators/nocms/blocks_generator.rb +15 -0
  26. data/lib/generators/nocms/templates/config/initializers/nocms/blocks.rb +43 -0
  27. data/lib/no_cms/blocks/configuration.rb +20 -0
  28. data/lib/no_cms/blocks/engine.rb +17 -0
  29. data/lib/no_cms/blocks/version.rb +5 -0
  30. data/lib/nocms-blocks.rb +7 -0
  31. data/lib/tasks/no_cms/blocks.rake +4 -0
  32. data/spec/dummy/README.rdoc +28 -0
  33. data/spec/dummy/Rakefile +6 -0
  34. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  35. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  36. data/spec/dummy/app/controllers/application_controller.rb +8 -0
  37. data/spec/dummy/app/controllers/home_controller.rb +3 -0
  38. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  39. data/spec/dummy/app/models/test_image.rb +5 -0
  40. data/spec/dummy/app/uploaders/logo_uploader.rb +51 -0
  41. data/spec/dummy/app/views/home/show.html.erb +3 -0
  42. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  43. data/spec/dummy/app/views/no_cms/blocks/blocks/_logo_caption.html.erb +5 -0
  44. data/spec/dummy/app/views/no_cms/blocks/blocks/_title_3_columns.html.erb +6 -0
  45. data/spec/dummy/bin/bundle +3 -0
  46. data/spec/dummy/bin/rails +4 -0
  47. data/spec/dummy/bin/rake +4 -0
  48. data/spec/dummy/config.ru +4 -0
  49. data/spec/dummy/config/application.rb +22 -0
  50. data/spec/dummy/config/boot.rb +5 -0
  51. data/spec/dummy/config/database.yml +25 -0
  52. data/spec/dummy/config/environment.rb +5 -0
  53. data/spec/dummy/config/environments/development.rb +29 -0
  54. data/spec/dummy/config/environments/production.rb +80 -0
  55. data/spec/dummy/config/environments/test.rb +38 -0
  56. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  57. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  58. data/spec/dummy/config/initializers/inflections.rb +16 -0
  59. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  60. data/spec/dummy/config/initializers/nocms/blocks.rb +43 -0
  61. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  62. data/spec/dummy/config/initializers/session_store.rb +3 -0
  63. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  64. data/spec/dummy/config/locales/en.yml +23 -0
  65. data/spec/dummy/config/routes.rb +5 -0
  66. data/spec/dummy/db/development.sqlite3 +0 -0
  67. data/spec/dummy/db/migrate/20140304094052_create_test_images.rb +9 -0
  68. data/spec/dummy/db/schema.rb +43 -0
  69. data/spec/dummy/db/test.sqlite3 +0 -0
  70. data/spec/dummy/log/development.log +40 -0
  71. data/spec/dummy/log/test.log +33500 -0
  72. data/spec/dummy/public/404.html +58 -0
  73. data/spec/dummy/public/422.html +58 -0
  74. data/spec/dummy/public/500.html +57 -0
  75. data/spec/dummy/public/favicon.ico +0 -0
  76. data/spec/dummy/public/uploads/test_image/logo/1/logo.png +0 -0
  77. data/spec/dummy/public/uploads/test_image/logo/1/logo2.png +0 -0
  78. data/spec/factories/no_cms/blocks/block.rb +8 -0
  79. data/spec/factories/test_image.rb +12 -0
  80. data/spec/fixtures/images/logo.png +0 -0
  81. data/spec/fixtures/images/logo2.png +0 -0
  82. data/spec/models/no_cms/blocks/block_spec.rb +200 -0
  83. data/spec/requests/no_cms/blocks/blocks_spec.rb +95 -0
  84. data/spec/spec_helper.rb +70 -0
  85. data/spec/support/concerns/model_with_has_many_relationship.rb +39 -0
  86. data/spec/support/concerns/model_with_required_attributes.rb +21 -0
  87. metadata +236 -0
data/README.md ADDED
@@ -0,0 +1,233 @@
1
+ # NoCMS Blocks
2
+
3
+ ## What's this?
4
+
5
+ This is a Rails engine with a basic functionality of customizable blocks of content attachable to objects. It's not attached to any particular CMS so you can use it freely within your Rails application without too much dependencies.
6
+
7
+ ## How do I install it?
8
+
9
+ Right now there's no proper gem, although we have a couple of projects making extensive use of it.
10
+
11
+ To install it just put the repo in your Gemfile:
12
+
13
+ ```ruby
14
+ gem "nocms-blocks", git: 'git@github.com:simplelogica/nocms-blocks.git'
15
+ ```
16
+
17
+ And then import all the migrations:
18
+
19
+ ```
20
+ rake no_cms_blocks:install:migrations
21
+ ```
22
+
23
+ And run the initializer:
24
+
25
+ ```
26
+ rails g nocms:blocks
27
+ ```
28
+
29
+ ## How does it works?
30
+
31
+ Blocks are thought to be independent and customizable modules of content that can be created, edited or removed on their own, without dependency of any other module or class.
32
+
33
+ ### Block layouts
34
+
35
+ In NoCMS Blocks, block layouts define two main things:
36
+
37
+ 1. What kind of information a block contains and other settings (i.e. cache settings).
38
+ 2. How this information is displayed on a view.
39
+
40
+ Block settings are configured in the file `config/initializers/nocms/blocks.rb`. In that file we declare all the available layouts for a block.
41
+
42
+ The following code
43
+
44
+ ```ruby
45
+ NoCms::Blocks.configure do |config|
46
+
47
+ config.block_layouts = {
48
+ 'default' => {
49
+ template: 'default',
50
+ fields: {
51
+ title: :string,
52
+ body: :text
53
+ }
54
+ },
55
+ 'title-3_columns' => {
56
+ template: 'title_3_columns',
57
+ fields: {
58
+ title: :string,
59
+ column_1: :text,
60
+ column_2: :text,
61
+ column_3: :text
62
+ },
63
+ },
64
+ 'logo-caption' => {
65
+ template: 'logo_caption',
66
+ fields: {
67
+ caption: :string,
68
+ logo: TestImage
69
+ }
70
+ }
71
+ }
72
+
73
+ end
74
+ ```
75
+
76
+ declares 3 layouts ('default', 'title-3_columns' and 'logo-caption'). Each layout has a template and some declared fields. These fields will be available in the ruby object for that block. As an example, if `@block` is an instance of the NoCms::Blocks::Block model which layout attribute is set to 'default' you will be able to do `@block.title`
77
+
78
+ ```ruby
79
+ block = NoCms::Blocks::Block.new
80
+ block.layout = 'default'
81
+
82
+ block.title = 'a title'
83
+ block.title # => 'a title'
84
+
85
+ block.column_1 = 'a column' # => NoMethodError
86
+ block.column_1 # => NoMethodError
87
+
88
+
89
+ block.layout = 'title-3_columns'
90
+
91
+ block.title # => 'a title'
92
+ block.column_1 = 'a column'
93
+ block.column_1 # => 'a column'
94
+ block.body # => NoMethodError
95
+
96
+ block.layout = 'logo_caption'
97
+ block.title # => NoMethodError
98
+ block.logo = { name: 'testing logo' } # Currently this is the way to assign objects
99
+ block.logo.name # => 'testing logo'
100
+ block.logo.class # => TestImage
101
+ block.logo = TestImage.new name: 'testing logo' # Error! Currently assigning the object is not allowed :(
102
+ ```
103
+
104
+ ### Block templates
105
+
106
+ Blocks are rendered using the `render_block` helper which controls all the logic related with renderinf a block, including fragment cache control.
107
+
108
+ In the end a partial is rendered using the block as a local variable to obtain the information. This partial must be found at `no_cms/blocks/blocks` views folder and have the name configured in the `template` setting of the block. This way, rendering a 'title-3_columns' would render the partial `/no_cms/blocks/blocks/title_3_columns`.
109
+
110
+ This partial is a regular Rails partial (nothing special here). As an example, this could be the content of our `/no_cms/blocks/blocks/title_3_columns.html.erb` partial:
111
+
112
+ ```html
113
+ <div class='columns_block'>
114
+ <h2 class="title"><%= block.title %></h2>
115
+ <p class="column_1"><%= block.column_1 %></p>
116
+ <p class="column_2"><%= block.column_2 %></p>
117
+ <p class="column_3"><%= block.column_3 %></p>
118
+ </div>
119
+ ```
120
+
121
+ As you can see, the partial has a `block` variable containing the block object you are rendering.
122
+
123
+ Since this is plain old rails you can do everything you can do with a partial (e.g. having a `/no_cms/blocks/blocks/title_3_columns.en.html.erb` for the english version and a `/no_cms/blocks/blocks/title_3_columns.es.html.erb` for the spanish one).
124
+
125
+ ### Block Cache
126
+
127
+ Since blocks are independent units of content, the standard Rails fragment cache seemed to fit well with them. That's why the `render_block` helper decides wether Rails cache should be used for rendering an individual block.
128
+
129
+ Cache for the blocks are configured at 3 levels:
130
+
131
+ 1. The `render_block` helper may be called with a `cache_enabled` option set to true or false. This option will enable/disable the cache. This allow us to render a block without using the cache (maybe on a preview action).
132
+
133
+ ```ruby
134
+ render_block block, cache: false
135
+ ```
136
+
137
+ 2. In the blocks configuration we can enable/disable the cache for all the blocks of a kind. We just have to add the `cache_enabled` setting.
138
+
139
+ ```ruby
140
+ NoCms::Blocks.configure do |config|
141
+
142
+ config.block_layouts = {
143
+ 'default' => {
144
+ template: 'default',
145
+ fields: {
146
+ title: :string,
147
+ body: :text
148
+ },
149
+ cache_enabled: false
150
+ }
151
+ }
152
+ end
153
+ ```
154
+
155
+ 3. In the blocks configuration file we can enable/disable cache for all the blocks that doesn't have a cache_enabled setting. This configuration will be stored at `NoCms::Blocks.cache_enabled`
156
+
157
+ ```ruby
158
+ NoCms::Blocks.configure do |config|
159
+
160
+ config.cache_enabled = true
161
+
162
+ end
163
+ ```
164
+
165
+ As a summary:
166
+
167
+ ```ruby
168
+
169
+ b = NoCms::Blocks::Block.new layout: 'default', title: 'Foo', description: 'Bar'
170
+ NoCms::Blocks.cache_enabled # => true
171
+ b.cache_enabled # => false, since the block configuration sets it to false
172
+ render_block b # => This won't use fragment cache since this block layout have cache disabled
173
+
174
+ b = NoCms::Blocks::Block.new layout: 'title-3_columns', title: 'Foo', description: 'Bar'
175
+ NoCms::Blocks.cache_enabled # => true
176
+ b.cache_enabled # => true, since this block configuration doesn't override NoCms::Block.cache_enabled
177
+ render_block b # => This will use fragment cache since, by default, it's enabled for all blocks
178
+
179
+ render_block b, cache_enabled: false # => This won't use fragment cache as the option in the helper overrides the block configuration
180
+
181
+ ```
182
+
183
+ ## Where is the admin interface?
184
+
185
+ Since blocks are always attached to another object there ¡s no separate admin interface for them.
186
+
187
+ Instead of a separate admin interface this engine includes a set of partials that can be used to render it as a basic admin interface attachable to any edit view of any object that has blocks attached.
188
+
189
+ ```ruby
190
+ <%= render 'no_cms/admin/blocks/blocks/index', f: f %>
191
+ ```
192
+
193
+ ### NoCms Admin
194
+
195
+ This partial is fully compatible with `nocms-admin` gem and works with the JS in that engine that handles creation or modification of blocks.
196
+
197
+ To enable it just add the following code to your form view.
198
+
199
+ ```ruby
200
+ <% content_for :ready_js do %>
201
+ NoCMS.Admin.BlockHandler();
202
+ <% end %>
203
+ ```
204
+
205
+ ### Block admin templates
206
+
207
+ Same way that a block has a partial that gets rendered in the public views it has another partial to be rendered inside the admin views if you use the no_cms/admin/blocks/blocks/index partial.
208
+
209
+ This partial must be found at `no_cms/admin/blocks/blocks` views folder and have the name configured in the `template` setting of the block. This way, rendering a 'title-3_columns' would render the partial `/no_cms/admin/blocks/blocks/title_3_columns`.
210
+
211
+ This partial is a regular Rails partial (nothing special here). As an example, this could be the content of our `/no_cms/admin/blocks/blocks/title_3_columns.html.erb` partial:
212
+
213
+ ```html
214
+ <div class="row">
215
+ <%= f.label :title %>
216
+ <%= f.text_field :title %>
217
+ </div>
218
+
219
+ <div class="row">
220
+ <%= f.label :column_1 %>
221
+ <%= f.text_area :column_1 %>
222
+ </div>
223
+
224
+ <div class="row">
225
+ <%= f.label :column_2 %>
226
+ <%= f.text_area :column_2 %>
227
+ </div>
228
+
229
+ <div class="row">
230
+ <%= f.label :column_3 %>
231
+ <%= f.text_area :column_3 %>
232
+ </div>
233
+ ```
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'NoCMS Blocks'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ Bundler::GemHelper.install_tasks
21
+
22
+ task :default => [:"app:spec"]
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,4 @@
1
+ module NoCms::Blocks
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,3 @@
1
+ NoCms::Blocks::Block.class_eval do
2
+ attr_accessor :no_cms_admin_template
3
+ end
@@ -0,0 +1,4 @@
1
+ module NoCms::Blocks
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,28 @@
1
+ module NoCms
2
+ module Blocks
3
+ module BlocksHelper
4
+ def render_block block, options = {}
5
+ return if block.draft && !options[:force_render_draft]
6
+ # If we don't have any option about cache enabled then we ask the block
7
+ options[:cache_enabled] = block.cache_enabled unless options.has_key? :cache_enabled
8
+
9
+ block_template = "no_cms/blocks/blocks/#{block.template}"
10
+
11
+ # And now decide if we use cache or not
12
+ if options[:cache_enabled]
13
+ Rails.cache.fetch cache_key_for_blocks(block, block_template, options) do
14
+ render block_template, block: block
15
+ end
16
+ else
17
+ render block_template, block: block
18
+ end
19
+
20
+ end
21
+
22
+ def cache_key_for_blocks block, block_template, options = {}
23
+ "#{block_template}/#{block.id}/#{block.updated_at.to_i}#{"/#{options[:initial_cache_key]}" unless options[:initial_cache_key] }"
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,160 @@
1
+ module NoCms::Blocks
2
+ class Block < ActiveRecord::Base
3
+
4
+ include NoCms::Blocks::Concerns::TranslationScopes
5
+
6
+ acts_as_nested_set
7
+
8
+ scope :drafts, ->() { where_with_locale(draft: true) }
9
+ scope :no_drafts, ->() { where_with_locale(draft: false) }
10
+ scope :roots, ->() { where parent_id: nil }
11
+
12
+ accepts_nested_attributes_for :children, allow_destroy: true
13
+
14
+ attr_reader :cached_objects
15
+
16
+ translates :layout, :fields_info, :draft
17
+ accepts_nested_attributes_for :translations
18
+
19
+ class Translation
20
+ serialize :fields_info, Hash
21
+ end
22
+
23
+ after_initialize :set_blank_fields
24
+ before_save :save_related_objects
25
+
26
+ validates :fields_info, presence: { allow_blank: true }
27
+ validates :layout, presence: true
28
+
29
+ def cache_enabled
30
+ layout_config.has_key?(:cache_enabled) ? layout_config[:cache_enabled] : NoCms::Blocks.cache_enabled
31
+ end
32
+
33
+
34
+ def layout_config
35
+ NoCms::Blocks.block_layouts.stringify_keys[layout]
36
+ end
37
+
38
+ def template
39
+ layout_config[:template] if layout_config
40
+ end
41
+
42
+ def has_field? field
43
+ # We have the field if...
44
+ !layout_config.nil? && # We have a layout configuration AND
45
+ (
46
+ !layout_config[:fields].symbolize_keys[field.to_sym].nil? || # We have this field OR
47
+ !layout_config[:fields].symbolize_keys[field.to_s.gsub(/\_id$/, '').to_sym].nil? # we remove the final _id and then we have the field
48
+ )
49
+ end
50
+
51
+ def field_type field
52
+ return nil unless has_field?(field)
53
+ layout_config[:fields].symbolize_keys[field.to_sym]
54
+ end
55
+
56
+ def read_field field
57
+ return nil unless has_field?(field)
58
+
59
+ value = fields_info[field.to_sym] || # first, we get the value
60
+ @cached_objects[field.to_sym] # or we get it from the cached objects
61
+
62
+ # If value is still nil, but the field exists we must get the object from the database
63
+ if value.nil?
64
+ field_type = field_type(field)
65
+ field_id = fields_info["#{field}_id".to_sym]
66
+ value = @cached_objects[field.to_sym] = field_type.find(field_id) unless field_id.nil?
67
+ end
68
+
69
+ # If value is still nil, and the field_type is an ActiveRecord class, then we
70
+ if value.nil? && field_type.is_a?(Class)
71
+ value = @cached_objects[field.to_sym] = field_type.new
72
+ end
73
+ value
74
+ end
75
+
76
+ def write_field field, value
77
+ return nil unless has_field?(field)
78
+ field_type = field_type field
79
+ # If field type is a model then we update the cached object
80
+ if field_type.is_a?(Class) && field_type < ActiveRecord::Base
81
+ # First, we initialize the object if we don't read the object (it loads it into the cached objects)
82
+ @cached_objects[field.to_sym] = field_type.new if read_field(field).nil?
83
+ # Then, assign attributes
84
+ @cached_objects[field.to_sym].assign_attributes value
85
+ else # If it's a model then a new object or update the previous one
86
+ self.fields_info = fields_info.merge field.to_sym => value # when updating through an object (i.e. the page updates through nested attributes) fields_info[field.to_sym] = value doesn't work. Kudos to Rubo for this fix
87
+ end
88
+ end
89
+
90
+ # In this missing method we check wether we're asking for one field
91
+ # in which case we will read or write ir
92
+ def method_missing(m, *args, &block)
93
+ # We get the name of the field stripping out the '=' for writers
94
+ field = m.to_s
95
+ write_accessor = field.ends_with? '='
96
+ field.gsub!(/\=$/, '')
97
+
98
+ # If this field actually exists, then we write it or read it.
99
+ if has_field?(field)
100
+ write_accessor ?
101
+ write_field(field, args.first) :
102
+ read_field(field.to_sym)
103
+ else
104
+ super
105
+ end
106
+ end
107
+
108
+ # When we are assigning attributes (this method is called in new, create...)
109
+ # we must split those fields from our current layout and those who are not
110
+ # (they must be attributes).
111
+ # Attributes are processed the usual way and fields are written later
112
+ def assign_attributes new_attributes
113
+ fields = []
114
+
115
+ set_blank_fields
116
+
117
+ # We get the layout
118
+ new_layout = new_attributes[:layout] || new_attributes['layout']
119
+ self.layout = new_layout unless new_layout.nil?
120
+
121
+ Rails.logger.info "Searching #{new_attributes.keys.inspect} fields in #{self.layout} layout"
122
+
123
+ # And now separate fields and attributes
124
+ fields = new_attributes.select{|k, _| has_field? k }.symbolize_keys
125
+ new_attributes.reject!{|k, _| has_field? k }
126
+
127
+ super(new_attributes)
128
+
129
+ Rails.logger.info "Writing #{fields.inspect} to #{self.layout} block"
130
+
131
+ fields.each do |field_name, value|
132
+ self.write_field field_name, value
133
+ end
134
+ end
135
+
136
+ def reload *args
137
+ @cached_objects = {}
138
+ super
139
+ end
140
+
141
+ private
142
+
143
+ def set_blank_fields
144
+ self.fields_info ||= {}
145
+ @cached_objects ||= {}
146
+ end
147
+
148
+ def save_related_objects
149
+ # Now we save each activerecord related object
150
+ cached_objects.each do |field, object|
151
+ # Notice that we don't care if the object is actually saved
152
+ # We don't care because there may be some cases where no real information is sent to an object but something is sent (i.e. the locale in a new Globalize translation) and then the object is created empty
153
+ # When this happens if we save! the object an error is thrown and we can't leave the object blank
154
+ if object.is_a?(ActiveRecord::Base) && object.save
155
+ fields_info["#{field}_id".to_sym] = object.id
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end