Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions app/models/learning_material.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,12 @@
# index_learning_materials_on_title (title)
#
class LearningMaterial < ApplicationRecord
# Map app-level attribute names to the current DB column names
# DB columns (per schema.rb): thumbnail, link
# App code expects: thumbnail_url, link_url
alias_attribute :thumbnail_url, :thumbnail
alias_attribute :link_url, :link

enum :level, { beginner: 0, intermediate: 1, expert: 2 }

validates :title, presence: true
validates :level, presence: true
validates :link_url, presence: true, format: URI::DEFAULT_PARSER.make_regexp(%w[http https])
validates :thumbnail_url, allow_blank: true, format: URI::DEFAULT_PARSER.make_regexp(%w[http https])
validates :link, presence: true, format: URI::DEFAULT_PARSER.make_regexp(%w[http https])
validates :thumbnail, allow_blank: true, format: URI::DEFAULT_PARSER.make_regexp(%w[http https])

scope :featured, -> { where(featured: true) }
scope :by_level, ->(lvl) { lvl.present? ? where(level: levels[lvl]) : all }
Expand Down
12 changes: 6 additions & 6 deletions app/views/learning_materials/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 gap-4">
<% @featured_materials.each do |m| %>
<div class="card bg-base-100 shadow-md overflow-hidden w-full transition-transform duration-300 hover:-translate-y-1 hover:shadow-xl">
<% if m.thumbnail_url.present? %>
<% if m.thumbnail.present? %>
<figure class="w-full aspect-[4/3] max-h-40 overflow-hidden">
<img src="<%= m.thumbnail_url %>" alt="<%= m.title %> thumbnail" class="w-full h-full object-cover transition-transform duration-300 ease-out hover:scale-105">
<img src="<%= m.thumbnail %>" alt="<%= m.title %> thumbnail" class="w-full h-full object-cover transition-transform duration-300 ease-out hover:scale-105">
</figure>
<% end %>
<div class="card-body p-2">
<span class="badge badge-secondary capitalize w-fit text-[10px]"><%= m.level %></span>
<h3 class="card-title text-lg text-black mt-1"><%= m.title %></h3>
<div class="card-actions justify-start mt-2">
<%= link_to 'Open resource', m.link_url, class: 'link link-primary text-sm transition-colors duration-200 hover:underline', target: '_blank', rel: 'noopener' %>
<%= link_to 'Open resource', m.link, class: 'link link-primary text-sm transition-colors duration-200 hover:underline', target: '_blank', rel: 'noopener' %>
</div>
</div>
</div>
Expand All @@ -50,16 +50,16 @@
<% @materials.each_with_index do |m, i| %>
<div class="pb-6 border-b border-dotted border-gray-300 w-full max-w-md"> <!-- from sm → md -->
<div class="card bg-base-100 shadow-md overflow-hidden w-full max-w-md transition-transform duration-300 hover:-translate-y-1 hover:shadow-xl"> <!-- slightly larger card -->
<% if m.thumbnail_url.present? %>
<% if m.thumbnail.present? %>
<figure class="w-full aspect-video max-h-48 overflow-hidden"> <!-- a little taller thumbnail -->
<img src="<%= m.thumbnail_url %>" alt="<%= m.title %> thumbnail" class="w-full h-full object-cover transition-transform duration-300 ease-out hover:scale-105">
<img src="<%= m.thumbnail %>" alt="<%= m.title %> thumbnail" class="w-full h-full object-cover transition-transform duration-300 ease-out hover:scale-105">
</figure>
<% end %>
<div class="card-body p-3 md:p-4"> <!-- slightly more breathing room -->
<span class="badge badge-ghost capitalize w-fit text-xs md:text-sm"><%= m.level %></span>
<h3 class="card-title text-base mt-1"><%= m.title %></h3>
<div class="card-actions justify-start mt-2">
<%= link_to 'Open resource', m.link_url, class: 'link link-primary text-sm transition-colors duration-200 hover:underline', target: '_blank', rel: 'noopener' %>
<%= link_to 'Open resource', m.link, class: 'link link-primary text-sm transition-colors duration-200 hover:underline', target: '_blank', rel: 'noopener' %>
</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions config/motor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ resources:
columns:
- name: title
- name: level
- name: link_url
- name: thumbnail_url
- name: link
- name: thumbnail
- name: featured
updated_at: 2025-09-10 22:08:00.000000000 +00:00
configs:
Expand Down
4 changes: 2 additions & 2 deletions db/migrate/20250907005500_create_learning_materials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def change
create_table :learning_materials do |t|
t.string :title, null: false
t.integer :level, null: false, default: 0
t.string :thumbnail_url
t.string :link_url, null: false
t.string :thumbnail
t.string :link, null: false
t.boolean :featured, null: false, default: false
t.text :description

Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20250912215406_rename_learning_materials_url_columns.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class RenameLearningMaterialsUrlColumns < ActiveRecord::Migration[7.2]
def change
if column_exists?(:learning_materials, :link_url)
rename_column :learning_materials, :link_url, :link
end

if column_exists?(:learning_materials, :thumbnail_url)
rename_column :learning_materials, :thumbnail_url, :thumbnail
end
end
end
2 changes: 1 addition & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
if defined?(LearningMaterial)
LearningMaterial.find_or_create_by!(title: 'Rails Guides') do |lm|
lm.level = :beginner
lm.thumbnail_url = 'https://rubyonrails.org/images/rails-logo.svg'
lm.link_url = 'https://guides.rubyonrails.org/'
lm.thumbnail = 'https://rubyonrails.org/images/rails-logo.svg'
lm.link = 'https://guides.rubyonrails.org/'
lm.featured = true
lm.description = 'Official Rails Guides for beginners to experts.'
end

LearningMaterial.find_or_create_by!(title: 'Ruby Official') do |lm|
lm.level = :intermediate
lm.thumbnail_url = 'https://www.ruby-lang.org/images/header-ruby-logo.png'
lm.link_url = 'https://www.ruby-lang.org/en/documentation/'
lm.thumbnail = 'https://www.ruby-lang.org/images/header-ruby-logo.png'
lm.link = 'https://www.ruby-lang.org/en/documentation/'
lm.featured = false
lm.description = 'Official Ruby documentation and resources.'
end
Expand Down
2 changes: 1 addition & 1 deletion test/controllers/learning_materials_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class LearningMaterialsControllerTest < ActionDispatch::IntegrationTest
# LearningMaterial.create!(
# title: "Material #{i}",
# level: :beginner,
# link_url: "https://example.com/#{i}"
# link: "https://example.com/#{i}"
# )
# end
#
Expand Down
3 changes: 1 addition & 2 deletions test/models/learning_material_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ class LearningMaterialTest < ActiveSupport::TestCase
assert_not lm.valid?
assert_includes lm.errors.attribute_names, :title
assert_includes lm.errors.attribute_names, :level
# model uses alias_attribute :link_url, :link
assert_includes lm.errors.attribute_names, :link_url
assert_includes lm.errors.attribute_names, :link
end

test 'enum levels' do
Expand Down
8 changes: 4 additions & 4 deletions test/system/learning_materials_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

class LearningMaterialsTest < ApplicationSystemTestCase
test 'view learning materials index with search and filter' do
LearningMaterial.create!(title: 'Ruby Basics', level: :beginner, link_url: 'https://ruby-lang.org',
thumbnail_url: 'https://example.com/a.png')
LearningMaterial.create!(title: 'Rails Advanced', level: :expert, link_url: 'https://rubyonrails.org',
thumbnail_url: 'https://example.com/b.png', featured: true)
LearningMaterial.create!(title: 'Ruby Basics', level: :beginner, link: 'https://ruby-lang.org',
thumbnail: 'https://example.com/a.png')
LearningMaterial.create!(title: 'Rails Advanced', level: :expert, link: 'https://rubyonrails.org',
thumbnail: 'https://example.com/b.png', featured: true)

visit learning_materials_path

Expand Down