browsing_history 0.0.2

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/.gitignore +15 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +89 -0
  5. data/.rubocop_todo.yml +28 -0
  6. data/.ruby-version +1 -0
  7. data/Gemfile +7 -0
  8. data/Gemfile.lock +180 -0
  9. data/LICENSE +21 -0
  10. data/MIT-LICENSE +20 -0
  11. data/README.md +2 -0
  12. data/README.rdoc +3 -0
  13. data/Rakefile +28 -0
  14. data/browsing_history.gemspec +34 -0
  15. data/dump.rdb +1 -0
  16. data/lib/browsing_history/browser.rb +66 -0
  17. data/lib/browsing_history/configuration.rb +38 -0
  18. data/lib/browsing_history/error.rb +2 -0
  19. data/lib/browsing_history/historizable.rb +26 -0
  20. data/lib/browsing_history/history.rb +85 -0
  21. data/lib/browsing_history/storage.rb +44 -0
  22. data/lib/browsing_history/storages/active_record.rb +12 -0
  23. data/lib/browsing_history/storages/base.rb +40 -0
  24. data/lib/browsing_history/storages/redis.rb +113 -0
  25. data/lib/browsing_history/version.rb +3 -0
  26. data/lib/browsing_history.rb +12 -0
  27. data/lib/generators/active_record/migration_generator.rb +12 -0
  28. data/lib/generators/active_record/templates/migration.rb +15 -0
  29. data/lib/tasks/browsing_history_tasks.rake +4 -0
  30. data/spec/browsing_history/browser_spec.rb +156 -0
  31. data/spec/browsing_history/configration_spec.rb +16 -0
  32. data/spec/browsing_history/fixtures/article.rb +10 -0
  33. data/spec/browsing_history/fixtures/user.rb +10 -0
  34. data/spec/browsing_history/historizable_spec.rb +27 -0
  35. data/spec/browsing_history/history_spec.rb +273 -0
  36. data/spec/browsing_history/storage_spec.rb +45 -0
  37. data/spec/browsing_history/storages/base_spec.rb +35 -0
  38. data/spec/browsing_history/storages/redis_spec.rb +141 -0
  39. data/spec/browsing_history_spec.rb +4 -0
  40. data/spec/generator_spec.rb +34 -0
  41. data/spec/spec_helper.rb +40 -0
  42. data/spec/test_app/README.rdoc +28 -0
  43. data/spec/test_app/Rakefile +6 -0
  44. data/spec/test_app/app/assets/images/.keep +0 -0
  45. data/spec/test_app/app/assets/javascripts/application.js +13 -0
  46. data/spec/test_app/app/assets/stylesheets/application.css +15 -0
  47. data/spec/test_app/app/controllers/application_controller.rb +10 -0
  48. data/spec/test_app/app/controllers/articles_controller.rb +17 -0
  49. data/spec/test_app/app/controllers/concerns/.keep +0 -0
  50. data/spec/test_app/app/helpers/application_helper.rb +2 -0
  51. data/spec/test_app/app/mailers/.keep +0 -0
  52. data/spec/test_app/app/models/.keep +0 -0
  53. data/spec/test_app/app/models/concerns/.keep +0 -0
  54. data/spec/test_app/app/views/layouts/application.html.erb +14 -0
  55. data/spec/test_app/bin/bundle +3 -0
  56. data/spec/test_app/bin/rails +4 -0
  57. data/spec/test_app/bin/rake +4 -0
  58. data/spec/test_app/bin/setup +29 -0
  59. data/spec/test_app/config/application.rb +19 -0
  60. data/spec/test_app/config/boot.rb +5 -0
  61. data/spec/test_app/config/database.yml +12 -0
  62. data/spec/test_app/config/environment.rb +5 -0
  63. data/spec/test_app/config/environments/development.rb +18 -0
  64. data/spec/test_app/config/environments/test.rb +21 -0
  65. data/spec/test_app/config/initializers/assets.rb +11 -0
  66. data/spec/test_app/config/initializers/backtrace_silencers.rb +7 -0
  67. data/spec/test_app/config/initializers/cookies_serializer.rb +3 -0
  68. data/spec/test_app/config/initializers/filter_parameter_logging.rb +4 -0
  69. data/spec/test_app/config/initializers/inflections.rb +16 -0
  70. data/spec/test_app/config/initializers/mime_types.rb +4 -0
  71. data/spec/test_app/config/initializers/session_store.rb +3 -0
  72. data/spec/test_app/config/initializers/wrap_parameters.rb +14 -0
  73. data/spec/test_app/config/locales/en.yml +23 -0
  74. data/spec/test_app/config/routes.rb +2 -0
  75. data/spec/test_app/config/secrets.yml +5 -0
  76. data/spec/test_app/config.ru +4 -0
  77. data/spec/test_app/db/development.sqlite3 +0 -0
  78. data/spec/test_app/db/test.sqlite3 +0 -0
  79. data/spec/test_app/lib/assets/.keep +0 -0
  80. data/spec/test_app/log/.keep +0 -0
  81. data/spec/test_app/log/development.log +0 -0
  82. data/spec/test_app/log/test.log +0 -0
  83. data/spec/test_app/public/404.html +67 -0
  84. data/spec/test_app/public/422.html +67 -0
  85. data/spec/test_app/public/500.html +66 -0
  86. data/spec/test_app/public/favicon.ico +0 -0
  87. metadata +342 -0
@@ -0,0 +1,273 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/user'
3
+ require 'fixtures/article'
4
+
5
+ describe BrowsingHistory::History do
6
+ let(:user) { User.new }
7
+ let(:article) { Article.new }
8
+ let(:articles) { Array.new(50) { |i| Article.new(i) } }
9
+ let(:history) { described_class.new(browser: user, historizable: article) }
10
+ let(:invalid_object) { Struct.new(:_).new }
11
+
12
+ describe 'responses' do
13
+ describe 'instance_methods' do
14
+ subject { history }
15
+
16
+ it { is_expected.to respond_to(:browser) }
17
+ it { is_expected.to respond_to(:historizable) }
18
+ it { is_expected.to respond_to(:save) }
19
+ it { is_expected.to respond_to(:save!) }
20
+ end
21
+
22
+ describe 'instance_methods' do
23
+ subject { described_class }
24
+
25
+ it { is_expected.to respond_to(:create) }
26
+ it { is_expected.to respond_to(:create!) }
27
+ it { is_expected.to respond_to(:where) }
28
+ it { is_expected.to respond_to(:count) }
29
+ end
30
+ end
31
+
32
+ describe '#save' do
33
+ let(:new_history_with_valid_objects) do
34
+ described_class.new(
35
+ browser: user,
36
+ historizable: article
37
+ )
38
+ end
39
+
40
+ let(:new_history_with_invalid_browser) do
41
+ described_class.new(
42
+ browser: invalid_object,
43
+ historizable: article
44
+ )
45
+ end
46
+
47
+ let(:new_history_with_invalid_historizable) do
48
+ described_class.new(
49
+ browser: user,
50
+ historizable: invalid_object
51
+ )
52
+ end
53
+
54
+ context 'when save with valid objects' do
55
+ it "should return #{described_class} instance" do
56
+ expect(
57
+ new_history_with_valid_objects.save
58
+ ).to be(true)
59
+
60
+ expect(
61
+ new_history_with_valid_objects.save!
62
+ ).to be(true)
63
+ end
64
+ end
65
+
66
+ context 'when save with invalid object' do
67
+ it 'should return nil' do
68
+ expect(
69
+ new_history_with_invalid_browser.save
70
+ ).to be_falsey
71
+
72
+ expect(
73
+ new_history_with_invalid_historizable.save
74
+ ).to be_falsey
75
+ end
76
+ end
77
+
78
+ context 'when save! with invalid object' do
79
+ it 'should raise error' do
80
+ expect do
81
+ new_history_with_invalid_browser.save!
82
+ end.to raise_error(BrowsingHistory::History::ArgumentError)
83
+
84
+ expect do
85
+ new_history_with_invalid_historizable.save!
86
+ end.to raise_error(BrowsingHistory::History::ArgumentError)
87
+ end
88
+ end
89
+
90
+ context 'after save hitorizables' do
91
+ before(:each) do
92
+ articles.each do |article|
93
+ described_class.new(browser: user, historizable: article).save
94
+ end
95
+ end
96
+
97
+ let(:saved_articles) do
98
+ described_class.where(
99
+ browser: user,
100
+ historizable: article
101
+ )
102
+ end
103
+
104
+ it 'should equal original historizable' do
105
+ saved_articles.each_with_index do |saved_article, i|
106
+ original = articles.reverse[i]
107
+
108
+ expect(saved_article.id).to eq(original.id)
109
+ expect(saved_article.title).to eq(original.title)
110
+ end
111
+ end
112
+ end
113
+
114
+ context 'after save! hitorizables' do
115
+ before(:each) do
116
+ articles.each do |article|
117
+ described_class.new(browser: user, historizable: article).save!
118
+ end
119
+ end
120
+
121
+ let(:saved_articles) do
122
+ described_class.where(
123
+ browser: user,
124
+ historizable: article
125
+ )
126
+ end
127
+
128
+ it 'should equal original historizable' do
129
+ saved_articles.each_with_index do |saved_article, i|
130
+ original = articles.reverse[i]
131
+
132
+ expect(saved_article.id).to eq(original.id)
133
+ expect(saved_article.title).to eq(original.title)
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ describe '.create' do
140
+ context 'when create with valid objects' do
141
+ subject do
142
+ described_class.create(
143
+ browser: user,
144
+ historizable: article
145
+ )
146
+ end
147
+ it { is_expected.to be_a(described_class) }
148
+
149
+ subject do
150
+ described_class.create!(
151
+ browser: user,
152
+ historizable: article
153
+ )
154
+ end
155
+ it { is_expected.to be_a(described_class) }
156
+ end
157
+
158
+ context 'when create with invalid object' do
159
+ it 'should return nil' do
160
+ expect(
161
+ described_class.create(
162
+ browser: invalid_object,
163
+ historizable: article
164
+ )
165
+ ).to be_falsey
166
+
167
+ expect(
168
+ described_class.create(
169
+ browser: user,
170
+ historizable: invalid_object
171
+ )
172
+ ).to be_falsey
173
+ end
174
+ end
175
+
176
+ context 'when create! with invalid object' do
177
+ it 'should raise error' do
178
+ expect do
179
+ described_class.create!(
180
+ browser: invalid_object,
181
+ historizable: article
182
+ )
183
+ end.to raise_error(BrowsingHistory::History::ArgumentError)
184
+
185
+ expect do
186
+ described_class.create!(
187
+ browser: user,
188
+ historizable: invalid_object
189
+ )
190
+ end.to raise_error(BrowsingHistory::History::ArgumentError)
191
+ end
192
+ end
193
+ end
194
+
195
+ describe '.count' do
196
+ subject { described_class.current_storage.count(user, article) }
197
+ it { is_expected.to eq(0) }
198
+ end
199
+
200
+ describe '.where' do
201
+ it 'should default empty' do
202
+ expect(
203
+ BrowsingHistory::History.where(
204
+ browser: user,
205
+ historizable: article
206
+ )
207
+ ).to be_empty
208
+ end
209
+
210
+ context 'with limit option' do
211
+ before do
212
+ 5.times do |i|
213
+ described_class.create(browser: user, historizable: Article.new(i))
214
+ end
215
+ end
216
+
217
+ let(:historizables) do
218
+ described_class.where(
219
+ browser: user,
220
+ historizable: article,
221
+ limit: 3
222
+ )
223
+ end
224
+
225
+ let(:historizables_excess_limit) do
226
+ described_class.where(
227
+ browser: user,
228
+ historizable: article,
229
+ limit: 100
230
+ )
231
+ end
232
+
233
+ it { expect(historizables).to be_a(Array) }
234
+ it { expect(historizables.size).to eq(3) }
235
+
236
+ it { expect(historizables_excess_limit).to be_a(Array) }
237
+ it { expect(historizables_excess_limit.size).to eq(5) }
238
+ end
239
+
240
+ context 'with between option' do
241
+ before do
242
+ 5.times.map.with_index(1) do |i|
243
+ described_class.create(browser: user, historizable: Article.new(i))
244
+ end
245
+
246
+ sleep(6)
247
+ described_class.create(browser: user, historizable: Article.new(100))
248
+ end
249
+
250
+ let(:historizables) do
251
+ described_class.where(
252
+ browser: user,
253
+ historizable: article,
254
+ between: Time.now..5.seconds.ago
255
+ )
256
+ end
257
+
258
+ let(:historizables_unhit) do
259
+ described_class.where(
260
+ browser: user,
261
+ historizable: article,
262
+ between: 1.day.ago..2.days.ago
263
+ )
264
+ end
265
+
266
+ it { expect(historizables).to be_a(Array) }
267
+ it { expect(historizables.size).to eq(1) }
268
+
269
+ it { expect(historizables_unhit).to be_a(Array) }
270
+ it { expect(historizables_unhit.size).to eq(0) }
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+
3
+ describe BrowsingHistory::Storage do
4
+ describe '#attach_storage' do
5
+ let(:default_storage) { :redis }
6
+
7
+ let(:include_class) do
8
+ Struct.new(:_) do
9
+ include BrowsingHistory::Storage
10
+ end
11
+ end
12
+
13
+ let(:include_class_attached_activerecord) do
14
+ Struct.new(:_) do
15
+ include BrowsingHistory::Storage
16
+ attach_storage :active_record
17
+ end
18
+ end
19
+
20
+ let(:include_class_invalid_storage) do
21
+ Struct.new(:_) do
22
+ include BrowsingHistory::Storage
23
+ attach_storage :invalid_storage
24
+ end
25
+ end
26
+
27
+ it 'should be attached redis storage default' do
28
+ expect(include_class.current_storage_type).to eql(default_storage)
29
+ end
30
+
31
+ it 'should attached activerecord' do
32
+ expect(
33
+ include_class_attached_activerecord.current_storage_type
34
+ ).to eql(:active_record)
35
+ end
36
+
37
+ context 'when passed invalid storage' do
38
+ it 'should raise error' do
39
+ expect do
40
+ include_class_invalid_storage
41
+ end.to raise_error(BrowsingHistory::Storage::InvalidStorage)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/user'
3
+ require 'fixtures/article'
4
+
5
+ describe BrowsingHistory::Storages::Base do
6
+ let(:user) { User.new }
7
+ let(:article) { Article.new }
8
+ let(:described_instance) { described_class.new(user, article) }
9
+ let(:test_options) { Hash.new }
10
+
11
+ before do
12
+ described_class.connect
13
+ end
14
+
15
+ describe 'io_methods' do
16
+ it 'should be defined on class' do
17
+ BrowsingHistory::Storages::IOMethods.each do |method|
18
+ expect(
19
+ described_class.respond_to?(method)
20
+ ).to be(true)
21
+ end
22
+ end
23
+
24
+ it 'should raise not overide error' do
25
+ BrowsingHistory::Storages::IOMethods.each do |method|
26
+ expect do
27
+ described_instance.send(method)
28
+ end.to raise_error(BrowsingHistory::Storages::NotOverideError)
29
+ end
30
+ end
31
+ end
32
+
33
+ describe '.connect' do
34
+ end
35
+ end
@@ -0,0 +1,141 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/user'
3
+ require 'fixtures/article'
4
+
5
+ describe BrowsingHistory::Storages::Redis do
6
+ articles_size = 5
7
+
8
+ let(:user) { User.new }
9
+ let(:articles) do
10
+ articles_size.times.map.with_index(1) { |i| Article.new(i) }
11
+ end
12
+ let(:article) { articles.first }
13
+
14
+ let(:storage) do
15
+ Struct.new(:_) do
16
+ include BrowsingHistory::Storage
17
+ attach_storage :redis
18
+ end.current_storage
19
+ end
20
+
21
+ describe 'method_defined?' do
22
+ describe 'public_instance_methods' do
23
+ subject { storage.new(user, article) }
24
+
25
+ it { is_expected.to respond_to(:fetch) }
26
+ it { is_expected.to respond_to(:add) }
27
+ it { is_expected.to respond_to(:update) }
28
+ it { is_expected.to respond_to(:clear) }
29
+ it { is_expected.to respond_to(:interface) }
30
+ end
31
+
32
+ describe 'private_instance_methods' do
33
+ subject { storage.private_instance_methods }
34
+
35
+ it { is_expected.to include(:history) }
36
+ it { is_expected.to include(:fetch_between) }
37
+ it { is_expected.to include(:clear_all) }
38
+ it { is_expected.to include(:clear_expiration) }
39
+ it { is_expected.to include(:score) }
40
+ it { is_expected.to include(:parse_between) }
41
+ end
42
+
43
+ describe 'singleton_methods' do
44
+ subject { storage }
45
+ it { is_expected.to respond_to(:connect) }
46
+ it { is_expected.to respond_to(:default_options) }
47
+ it { is_expected.to respond_to(:default_connect_options) }
48
+
49
+ it { is_expected.to respond_to(:redis) }
50
+ it { is_expected.to respond_to(:set) }
51
+ end
52
+ end
53
+
54
+ describe '#fetch' do
55
+ context 'when add 1 object' do
56
+ it 'should return articles' do
57
+ expect { storage.add(user, article) }
58
+ .to change { storage.fetch(user, article).size }.by(1)
59
+ end
60
+ end
61
+
62
+ context "when add #{articles_size} object" do
63
+ it 'should return articles' do
64
+ expect do
65
+ articles.each { |article| storage.add(user, article) }
66
+ end.to change { storage.fetch(user, article).size }.by(articles_size)
67
+ end
68
+ end
69
+ end
70
+
71
+ describe '#add' do
72
+ let(:history_key) do
73
+ %(\
74
+ #{user.browser_type}/\
75
+ #{user.browser_id}/\
76
+ #{article.historizable_type}\
77
+ ).delete(' ')
78
+ end
79
+
80
+ context 'when add 1 object' do
81
+ before { storage.add(user, article) }
82
+ it { expect(storage.redis.exists(history_key)).to be(true) }
83
+ end
84
+ end
85
+
86
+ describe '#update' do
87
+ end
88
+
89
+ describe '#clear' do
90
+ before(:each) { articles.each { |article| storage.add(user, article) } }
91
+
92
+ it 'should clear 1 historizable' do
93
+ expect { storage.clear(user, article, article) }
94
+ .to change { storage.fetch(user, article).size }.by(-1)
95
+ end
96
+
97
+ it 'should celar all historizables' do
98
+ expect { storage.clear(user, article, all: true) }
99
+ .to change { storage.fetch(user, article).size }.to(0)
100
+ end
101
+
102
+ context 'and add 1 historizable after 6 seconds' do
103
+ before do
104
+ sleep(6)
105
+ storage.add(user, Article.new(100))
106
+ end
107
+
108
+ it 'should celar 5 historizables' do
109
+ expect { storage.clear(user, article, expiration: 5.seconds.ago) }
110
+ .to change { storage.fetch(user, article).size }.to(1)
111
+ end
112
+ end
113
+ end
114
+
115
+ describe '#count' do
116
+ before(:each) { articles.each { |article| storage.add(user, article) } }
117
+
118
+ context "when exist #{articles_size} historizable" do
119
+ subject { storage.count(user, article) }
120
+ it { is_expected.to be(articles_size) }
121
+ end
122
+
123
+ context 'and add 1 historizable after 6 seconds' do
124
+ before do
125
+ sleep(6)
126
+ storage.add(user, Article.new(100))
127
+ end
128
+
129
+ subject { storage.count(user, article, between: Time.now..5.seconds.ago) }
130
+ it { is_expected.to be(1) }
131
+ end
132
+ end
133
+
134
+ describe '#interface' do
135
+ subject { storage.set }
136
+ it { is_expected.to be(Redis::SortedSet) }
137
+ end
138
+
139
+ describe '.connect' do
140
+ end
141
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe BrowsingHistory do
4
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+ require 'generator_spec'
3
+ require 'generator_spec/test_case'
4
+
5
+ require 'generators/active_record/migration_generator'
6
+
7
+ describe BrowsingHistory::MigrationGenerator, type: :generator do
8
+ include GeneratorSpec::TestCase
9
+ destination File.expand_path('tmp', __dir__)
10
+
11
+ after(:all) { prepare_destination } # cleanup the tmp directory
12
+
13
+ describe 'no options' do
14
+ before(:all) do
15
+ prepare_destination
16
+ run_generator
17
+ end
18
+
19
+ it 'generates a migration for creating browsing_histories table' do
20
+ expect(destination_root).to have_structure do
21
+ directory 'db' do
22
+ directory 'migrate' do
23
+ migration 'create_browsing_histories' do
24
+ contains 'class CreateBrowsingHistories'
25
+ contains 'def up'
26
+ contains 'create_table :browsing_histories'
27
+ contains 'def down'
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,40 @@
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+ ENV['DB'] ||= 'sqlite'
3
+
4
+ require 'pry'
5
+ require 'rails/all'
6
+ require 'rspec/rails'
7
+ require 'database_cleaner'
8
+
9
+ require 'browsing_history'
10
+
11
+ $LOAD_PATH.unshift File.expand_path(__dir__)
12
+ $LOAD_PATH.unshift File.expand_path('browsing_history', __dir__)
13
+
14
+ require File.expand_path('test_app/config/environment', __dir__)
15
+
16
+ RSpec.configure do |config|
17
+ redis = BrowsingHistory::History.storages[:redis].redis
18
+
19
+ config.mock_with :rspec
20
+ config.before(:suite) do
21
+ DatabaseCleaner[:redis].db = redis.client.id
22
+ DatabaseCleaner.strategy = :truncation
23
+ DatabaseCleaner.clean_with(:truncation)
24
+ end
25
+
26
+ config.before(:each) do
27
+ DatabaseCleaner.start
28
+ DatabaseCleaner.clean
29
+ redis.flushdb
30
+ end
31
+
32
+ config.after(:each) do
33
+ DatabaseCleaner.clean
34
+ redis.redis.quit
35
+ end
36
+ end
37
+
38
+ def random_string(length = 8)
39
+ (0...length).map { (65 + rand(26)).chr }.join
40
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
File without changes
@@ -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 any plugin's vendor/assets/javascripts directory 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/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
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 any plugin's vendor/assets/stylesheets directory 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 bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,10 @@
1
+ class ApplicationController < ApplicationController
2
+ before_action :set_user
3
+
4
+ private
5
+
6
+ def set_user
7
+ @user = User.new
8
+ end
9
+ end
10
+
@@ -0,0 +1,17 @@
1
+ class AriclesController < ApplicationController
2
+ before_action :set_article
3
+ before_action :add_user_history
4
+
5
+ def show
6
+ end
7
+
8
+ private
9
+
10
+ def set_article
11
+ @article = Article.new
12
+ end
13
+
14
+ def add_user_history
15
+
16
+ end
17
+ end
File without changes
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
File without changes
File without changes
File without changes