Skip to content

Commit de96fbb

Browse files
authored
Article and DevTo Models (#8)
1 parent f49b762 commit de96fbb

16 files changed

+279
-1
lines changed

.reek.yml

+9
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,14 @@ detectors:
22
IrresponsibleModule:
33
enabled: false
44

5+
directories:
6+
"db/migrate":
7+
FeatureEnvy:
8+
enabled: false
9+
TooManyStatements:
10+
enabled: false
11+
UncommunicativeVariableName:
12+
enabled: false # this is set on false because 't' from migrations are flagged
13+
514
exclude_paths:
615
- test

app/models/concerns/entryable.rb

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
module Entryable
4+
extend ActiveSupport::Concern
5+
6+
included do
7+
has_one :entry, as: :entryable, dependent: :destroy, touch: true
8+
end
9+
end

app/models/dev_to.rb

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
module DevTo
4+
def self.table_name_prefix
5+
"dev_to_"
6+
end
7+
end

app/models/dev_to/article.rb

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
class DevTo::Article < ApplicationRecord
4+
include Entryable
5+
6+
belongs_to(
7+
:author,
8+
class_name: "DevTo::Author",
9+
foreign_key: "dev_to_author_id",
10+
inverse_of: :articles,
11+
optional: true
12+
)
13+
14+
validates :title, presence: true
15+
validates :published_at, presence: true
16+
end

app/models/dev_to/author.rb

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
3+
class DevTo::Author < ApplicationRecord
4+
has_many(
5+
:articles,
6+
class_name: "DevTo::Article",
7+
dependent: :destroy,
8+
foreign_key: "dev_to_author_id",
9+
inverse_of: :author
10+
)
11+
12+
validates :name, presence: true
13+
validates :website_url, presence: true
14+
validates :original_unique_id, presence: true
15+
end

app/models/entry.rb

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# frozen_string_literal: true
2+
3+
class Entry < ApplicationRecord
4+
delegated_type :entryable, types: %w[Message Comment]
5+
6+
validates :url, presence: true
7+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
3+
class CreateEntries < ActiveRecord::Migration[7.0]
4+
def change
5+
create_table :entries do |t|
6+
t.string :url, null: false
7+
t.string :entryable_type, null: false
8+
t.integer :entryable_id, null: false
9+
t.timestamps
10+
end
11+
12+
add_index :entries, :url
13+
add_index :entries, [:entryable_type, :entryable_id]
14+
end
15+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# frozen_string_literal: true
2+
3+
class CreateDevToArticles < ActiveRecord::Migration[7.0]
4+
def change
5+
create_table :dev_to_articles do |t|
6+
t.string :title, null: false
7+
t.string :description, null: true
8+
t.datetime :published_at, null: false
9+
t.integer :dev_to_author_id, null: true
10+
t.json :data
11+
t.timestamps
12+
end
13+
14+
add_index :dev_to_articles, :title
15+
end
16+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# frozen_string_literal: true
2+
3+
class CreateDevToAuthors < ActiveRecord::Migration[7.0]
4+
def change
5+
create_table :dev_to_authors do |t|
6+
t.string :username
7+
t.string :original_unique_id
8+
t.string :name
9+
t.string :summary
10+
t.string :website_url
11+
t.string :profile_image_url
12+
t.string :twitter_username
13+
t.string :github_username
14+
t.json :data
15+
t.timestamps
16+
end
17+
end
18+
end

db/schema.rb

+35-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/fixtures/dev_to/articles.yml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2+
3+
# This model initially had no columns defined. If you add columns to the
4+
# model remove the "{}" from the fixture names and add the columns immediately
5+
# below each fixture, per the syntax in the comments below
6+
#
7+
one:
8+
id: 1
9+
title: "How to use fixtures"
10+
description: "It is all about fixtures"
11+
published_at: <%= 5.days.ago.to_fs(:db) %>
12+
data: {}
13+
created_at: <%= 2.days.ago.to_fs(:db) %>
14+
updated_at: <%= Time.current %>
15+
16+
two:
17+
id: 2
18+
title: "How to use Ruby"
19+
description: "Ruby is a great programming language"
20+
published_at: <%= 1.day.ago.to_fs(:db) %>
21+
author: kai
22+
data: {}
23+
created_at: <%= 2.days.ago.to_fs(:db) %>
24+
updated_at: <%= Time.current %>

test/fixtures/dev_to/authors.yml

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2+
3+
# This model initially had no columns defined. If you add columns to the
4+
# model remove the "{}" from the fixture names and add the columns immediately
5+
# below each fixture, per the syntax in the comments below
6+
#
7+
kai:
8+
username: "kai"
9+
original_unique_id: "100"
10+
name: "Kai Kap"
11+
summary: "This is Kay profile"
12+
website_url: "https://example.com/kai"
13+
profile_image_url: "https://i.pravatar.cc/300"
14+
twitter_username: "kai"
15+
github_username: "kai"
16+
data: {}
17+
created_at: <%= Time.current %>
18+
updated_at: <%= Time.current %>
19+
20+
ari:
21+
username: "ari"
22+
original_unique_id: "200"
23+
name: "Ari Arison"
24+
summary: "This is Ari's profile"
25+
website_url: "https://example.com/ari"
26+
profile_image_url: "https://i.pravatar.cc/300"
27+
twitter_username: "ari"
28+
github_username: "ari"
29+
data: {}
30+
created_at: <%= Time.current %>
31+
updated_at: <%= Time.current %>

test/fixtures/entries.yml

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2+
3+
# This model initially had no columns defined. If you add columns to the
4+
# model remove the "{}" from the fixture names and add the columns immediately
5+
# below each fixture, per the syntax in the comments below
6+
#
7+
one:
8+
entryable_type: "DevTo::Article"
9+
entryable_id: 1
10+
url: "https://newsletter.shortruby.com/p/short-ruby-news-edition-29"
11+
created_at: <%= 2.days.ago.to_fs(:db) %>
12+
updated_at: <%= Time.current %>
13+
14+
two:
15+
entryable_type: "DevTo::Article"
16+
entryable_id: 2
17+
url: "https://newsletter.shortruby.com/p/edition-28"
18+
created_at: <%= 2.days.ago.to_fs(:db) %>
19+
updated_at: <%= Time.current %>

test/models/dev_to/article_test.rb

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
require "test_helper"
4+
5+
class DevTo::ArticleTest < ActiveSupport::TestCase
6+
test "article is valid with title and published_at" do
7+
author = dev_to_authors(:kai)
8+
dev_to_article = DevTo::Article.new(
9+
author:,
10+
published_at: 1.day.ago,
11+
title: "This is my first article"
12+
)
13+
14+
assert_predicate(
15+
dev_to_article,
16+
:valid?,
17+
"Model should be valid but found: #{dev_to_article.errors.full_messages.join(', ')}"
18+
)
19+
end
20+
end

test/models/dev_to/author_test.rb

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
require "test_helper"
4+
5+
class DevTo::AuthorTest < ActiveSupport::TestCase
6+
test "author is valid with name, original_unique_id and website_url" do
7+
dev_to_author = DevTo::Author.new(
8+
name: "A",
9+
original_unique_id: SecureRandom.uuid,
10+
website_url: "https://example.com/author"
11+
)
12+
13+
assert_predicate(
14+
dev_to_author,
15+
:valid?,
16+
"Model should be valid but found: #{dev_to_author.errors.full_messages.join(', ')}"
17+
)
18+
end
19+
end

test/models/entry_test.rb

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
require "test_helper"
4+
5+
class EntryTest < ActiveSupport::TestCase
6+
test "can create delegated type" do
7+
dev_to_article = dev_to_articles(:one)
8+
entry = Entry.create(
9+
entryable: dev_to_article,
10+
url: "https://newsletter.shortruby.com"
11+
)
12+
13+
assert_predicate(
14+
entry,
15+
:persisted?,
16+
"Entry cannot be saved due to the following errors: #{entry.errors.full_messages.join(', ')}"
17+
)
18+
end
19+
end

0 commit comments

Comments
 (0)