action-draft 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5b73826fe9719191f155c5e59f291f250baf2180c1c690d801dfccd82d9960f6
4
+ data.tar.gz: 29d365a7dfbfb663474e68d096437de5b5d30df26eab7a29e7fe150ba0f10186
5
+ SHA512:
6
+ metadata.gz: c348a4e420d9ecc51d9eb201188e0c7f2ba67e1c95872877f45a8d1fe26ae9287e9fcf4c841964eb6da184ec1a43463a413d0e27a152b1e8d0f66430e12348c6
7
+ data.tar.gz: 914c21a224f2ba53a37786a18820580b9b67b207a2c1a6cdf9d07d8f94f8addf8f9c79489e49aed4a0237df3294957e109766f694a591b56df44acaf17bec83c
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ 0.1.0
2
+ -----
3
+
4
+ First commit.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2019 Jason Lee
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.md ADDED
@@ -0,0 +1,72 @@
1
+ # Action Draft
2
+
3
+ Action Draft brings your ActiveRecord model to storage multiple draft attributes without add any columns to table.
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/action-draft.svg)](https://rubygems.org/gems/action-draft) [![Build Status](https://travis-ci.org/rails-engine/action-draft.svg?branch=master)](https://travis-ci.org/rails-engine/action-draft)
6
+
7
+ ## Installation
8
+
9
+ ```ruby
10
+ gem "action-draft"
11
+ ```
12
+
13
+ And then execute:
14
+ ```bash
15
+ $ bundle
16
+ $ rails action_draft:install
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ In your ActiveRecord model:
22
+
23
+ ```rb
24
+ # app/models/message.rb
25
+ class Message < ApplicationRecord
26
+ has_draft :title, :content
27
+ end
28
+ ```
29
+
30
+ Now you have `draft_title`, `draft_content` attributes.
31
+
32
+ Then refer to this field in the form for the model:
33
+
34
+ ```erb
35
+ <%# app/views/messages/_form.html.erb %>
36
+ <%= form_with(model: message) do |form| %>
37
+
38
+ <div class="field">
39
+ <%= form.label :draft_title %>
40
+ <%= form.textarea :draft_title %>
41
+ </div>
42
+
43
+ <div class="field">
44
+ <%= form.label :draft_content %>
45
+ <%= form.textarea :draft_content %>
46
+ </div>
47
+
48
+ <% end %>
49
+ ```
50
+
51
+ Save draft attributes:
52
+
53
+ ```rb
54
+ irb> message = Message.new
55
+ irb> message.draft_title = "Draft title"
56
+ irb> message.draft_title.to_s
57
+ "Draft title"
58
+ irb> message.draft_content = "Draft message content"
59
+ irb> message.draft_content.to_s
60
+ "Draft message content"
61
+ irb> message.save
62
+
63
+ ir> message.reload
64
+ irb> message.draft_title.to_s
65
+ "Draft title"
66
+ irb> message.draft_content.to_s
67
+ "Draft message content"
68
+ ```
69
+
70
+ ## License
71
+
72
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionDraft
4
+ class ApplicationRecord < ActiveRecord::Base
5
+ self.abstract_class = true
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ActionDraft::Content < ApplicationRecord
4
+ self.table_name = "action_draft_contents"
5
+
6
+ belongs_to :record, polymorphic: true, touch: true
7
+
8
+ delegate :to_s, :nil?, :blank?, :present?, to: :content
9
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ ActionDraft::Engine.routes.draw do
4
+ resources :drafts
5
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateActionDraftContents < ActiveRecord::Migration[6.0]
4
+ def change
5
+ create_table :action_draft_contents do |t|
6
+ t.references :record, null: false, polymorphic: true, index: false
7
+ t.string :name
8
+ t.text :content, limit: 16777215
9
+
10
+ t.timestamps
11
+
12
+ t.index [ :record_type, :record_id, :name ], name: "index_action_drafts_uniqueness", unique: true
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "action-draft/version"
4
+ require "action-draft/attribute"
5
+ require "action-draft/engine"
6
+
7
+ module ActionDraft
8
+ # Your code goes here...
9
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionDraft
4
+ module Attribute
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ class_attribute :__action_draft_names
9
+ end
10
+
11
+ class_methods do
12
+ # Provides access to a dependent ActionDraft::Content model that holds the draft attributes.
13
+ # This dependent attribute is lazily instantiated and will be auto-saved when it's been changed. Example:
14
+ #
15
+ # class Message < ActiveRecord::Base
16
+ # has_draft :title, :content
17
+ # end
18
+ #
19
+ # message = Message.create!(draft_title: "This is draft title", draft_content: "<h1>Funny times!</h1>")
20
+ # message.draft_title # => "This is draft title"
21
+ # message.draft_content # => "<h1>Funny times!</h1>"
22
+ #
23
+ # If you wish to preload the dependent ActionDraft::Content model, you can use the named scope:
24
+ #
25
+ # Message.all.with_draft_title # Avoids N+1 queries when you just want the draft fields.
26
+ def has_draft(*names)
27
+ __action_draft_names ||= []
28
+ names = Array(names)
29
+ names.each do |name|
30
+ __action_draft_names << name
31
+
32
+ class_eval <<-CODE, __FILE__, __LINE__ + 1
33
+ def draft_#{name}
34
+ self.draft_#{name}_content ||= ActionDraft::Content.new(name: "#{name}", record: self)
35
+ end
36
+
37
+ def draft_#{name}=(content)
38
+ self.draft_#{name}.content = content
39
+ end
40
+ CODE
41
+
42
+ has_one :"draft_#{name}_content", -> { where(name: name) }, class_name: "ActionDraft::Content", as: :record, inverse_of: :record, dependent: :destroy
43
+ end
44
+
45
+ scope :with_drafts, -> do
46
+ names = __action_draft_names.map { |name| "draft_#{name}_content" }
47
+ includes(*names)
48
+ end
49
+
50
+ after_save do
51
+ __action_draft_names.each do |name|
52
+ public_send("draft_#{name}").save if public_send("draft_#{name}").changed?
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionDraft
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace ActionDraft
6
+ config.eager_load_namespaces << ActionDraft
7
+
8
+ initializer "action_draft.attribute" do
9
+ ActiveSupport.on_load(:active_record) do
10
+ include ActionDraft::Attribute
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionDraft
4
+ VERSION = "0.1.0"
5
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: action-draft
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jason Lee
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-07-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Help your ActiveRecord model to storage draft field.
42
+ email:
43
+ - huacnlee@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - CHANGELOG.md
49
+ - MIT-LICENSE
50
+ - README.md
51
+ - app/models/action_draft/application_record.rb
52
+ - app/models/action_draft/content.rb
53
+ - config/routes.rb
54
+ - db/migrate/20190724102032_create_action_draft_contents.rb
55
+ - lib/action-draft.rb
56
+ - lib/action-draft/attribute.rb
57
+ - lib/action-draft/engine.rb
58
+ - lib/action-draft/version.rb
59
+ homepage: http://github.com/rails-engine/action-draft
60
+ licenses:
61
+ - MIT
62
+ metadata: {}
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubygems_version: 3.0.3
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: Help your ActiveRecord model to storage draft field.
82
+ test_files: []