From b5ada8856b6aa7328ac282c9c4573ace9d1da116 Mon Sep 17 00:00:00 2001 From: Adam McKerlie Date: Mon, 30 Jun 2025 13:46:15 -0400 Subject: [PATCH] Add endpoint for Builders app --- app/controllers/builders_controller.rb | 24 ++++++ app/models/canadian_builder.rb | 20 +++++ app/views/builders/show.json.jbuilder | 5 ++ config/routes.rb | 1 + ...20250630162816_create_canadian_builders.rb | 21 +++++ db/schema.rb | 21 ++++- db/seeds/canada.rb | 84 +++++++++++++++++++ 7 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 app/controllers/builders_controller.rb create mode 100644 app/models/canadian_builder.rb create mode 100644 app/views/builders/show.json.jbuilder create mode 100644 db/migrate/20250630162816_create_canadian_builders.rb diff --git a/app/controllers/builders_controller.rb b/app/controllers/builders_controller.rb new file mode 100644 index 0000000..2da8673 --- /dev/null +++ b/app/controllers/builders_controller.rb @@ -0,0 +1,24 @@ +class BuildersController < ApplicationController + before_action :set_canadian_builder, only: %i[ show ] + + # GET /builders + def index + @canadian_builders = CanadianBuilder.order(:name) + render json: @canadian_builders.as_json(only: [ :id, :name, :title, :location, :description, :category, :slug ]) + end + + # GET /builders/1 + def show + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_canadian_builder + id = params.expect(:id) + if id.match(/[0-9]/) + @canadian_builder = CanadianBuilder.find(id) + else + @canadian_builder = CanadianBuilder.find_by(slug: id) + end + end +end \ No newline at end of file diff --git a/app/models/canadian_builder.rb b/app/models/canadian_builder.rb new file mode 100644 index 0000000..3499ced --- /dev/null +++ b/app/models/canadian_builder.rb @@ -0,0 +1,20 @@ +class CanadianBuilder < ApplicationRecord + belongs_to :government + + validates :name, presence: true + validates :title, presence: true + validates :location, presence: true + validates :category, presence: true + validates :description, presence: true + validates :achievement, presence: true + validates :avatar, presence: true + validates :website, format: { with: URI::DEFAULT_PARSER.make_regexp(%w[http https]), message: "must be a valid URL" }, allow_blank: true + + before_validation :generate_slug, on: :create + + private + + def generate_slug + self.slug = name.parameterize if name.present? + end +end \ No newline at end of file diff --git a/app/views/builders/show.json.jbuilder b/app/views/builders/show.json.jbuilder new file mode 100644 index 0000000..5a5ba5b --- /dev/null +++ b/app/views/builders/show.json.jbuilder @@ -0,0 +1,5 @@ +json.(@canadian_builder, :id, :name, :title, :location, :category, :description, :achievement, :avatar, :website, :slug) + +json.government do + json.(@canadian_builder.government, :id, :name) +end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 62b3a15..0d5c6be 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -17,6 +17,7 @@ resources :departments, only: [ :index, :show ] resources :promises, only: [ :index, :show ] resources :evidences, only: [ :index, :show ] + resources :builders, only: [ :index, :show ] namespace :admin do resources :promises, only: [ :index, :show, :update, :destroy ] diff --git a/db/migrate/20250630162816_create_canadian_builders.rb b/db/migrate/20250630162816_create_canadian_builders.rb new file mode 100644 index 0000000..59efc11 --- /dev/null +++ b/db/migrate/20250630162816_create_canadian_builders.rb @@ -0,0 +1,21 @@ +class CreateCanadianBuilders < ActiveRecord::Migration[8.0] + def change + create_table :canadian_builders do |t| + t.string :name, null: false + t.string :title, null: false + t.string :location, null: false + t.string :category, null: false + t.text :description, null: false + t.text :achievement, null: false + t.string :avatar, null: false + t.string :website + t.string :slug, null: false + t.references :government, null: false, foreign_key: true + + t.timestamps + end + + add_index :canadian_builders, :slug, unique: true + add_index :canadian_builders, :category + end +end diff --git a/db/schema.rb b/db/schema.rb index 9bd21ca..89b6810 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_06_23_150313) do +ActiveRecord::Schema[8.0].define(version: 2025_06_30_162816) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" @@ -56,6 +56,24 @@ t.index ["government_id"], name: "index_activities_on_government_id" end + create_table "canadian_builders", force: :cascade do |t| + t.string "name", null: false + t.string "title", null: false + t.string "location", null: false + t.string "category", null: false + t.text "description", null: false + t.text "achievement", null: false + t.string "avatar", null: false + t.string "website" + t.string "slug", null: false + t.bigint "government_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["category"], name: "index_canadian_builders_on_category" + t.index ["government_id"], name: "index_canadian_builders_on_government_id" + t.index ["slug"], name: "index_canadian_builders_on_slug", unique: true + end + create_table "chats", force: :cascade do |t| t.string "model_id" t.bigint "record_id" @@ -380,6 +398,7 @@ add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "activities", "entries" add_foreign_key "activities", "governments" + add_foreign_key "canadian_builders", "governments" add_foreign_key "department_promises", "departments" add_foreign_key "department_promises", "promises" add_foreign_key "departments", "governments" diff --git a/db/seeds/canada.rb b/db/seeds/canada.rb index 5f74463..a1ed7e2 100644 --- a/db/seeds/canada.rb +++ b/db/seeds/canada.rb @@ -547,6 +547,90 @@ require_relative 'department_promises' +puts "Seeding Canadian Builders..." + +builders_data = [ + { + id: 1, + name: "Ryan Reynolds", + title: "Actor & Entrepreneur", + location: "Vancouver, BC", + category: "Entertainment", + description: + "From Vancouver comedy clubs to Hollywood A-lister, Ryan built a media empire spanning film, spirits, and sports. His authentic voice and business acumen turned him into one of the most influential Canadian exports.", + achievement: "Built multiple 9-figure businesses while maintaining authentic Canadian humor", + avatar: "/placeholder.svg?height=120&width=120", + }, + { + id: 2, + name: "Tobias Lütke", + title: "Founder & CEO, Shopify", + location: "Ottawa, ON", + category: "Technology", + description: + "A German immigrant who couldn't find good e-commerce software, so he built Shopify. Today, his platform powers over 4 million businesses worldwide and has created countless entrepreneurial success stories.", + achievement: "Democratized e-commerce for millions of entrepreneurs globally", + avatar: "/placeholder.svg?height=120&width=120", + }, + { + id: 3, + name: "Margaret Atwood", + title: "Author & Visionary", + location: "Toronto, ON", + category: "Literature", + description: + "Her dystopian masterpiece 'The Handmaid's Tale' predicted societal challenges decades before they emerged. Margaret's work continues to shape global conversations about freedom, power, and human rights.", + achievement: "Authored works that became cultural phenomena and social movements", + avatar: "/placeholder.svg?height=120&width=120", + }, + { + id: 4, + name: "Chris Hadfield", + title: "Astronaut & Inspiration Leader", + location: "Milton, ON", + category: "Science", + description: + "From small-town Ontario to commanding the International Space Station, Chris showed the world that Canadians can reach for the stars. His space videos inspired millions to pursue STEM careers.", + achievement: "First Canadian to command the International Space Station", + avatar: "/placeholder.svg?height=120&width=120", + }, + { + id: 5, + name: "Céline Dion", + title: "Global Music Icon", + location: "Charlemagne, QC", + category: "Music", + description: + "From singing in her family's piano bar to selling 250+ million records worldwide, Céline proved that talent, determination, and authenticity can conquer any stage. Her voice became Canada's gift to the world.", + achievement: "One of the best-selling music artists of all time with 250M+ records sold", + avatar: "/placeholder.svg?height=120&width=120", + }, + { + id: 6, + name: "David Suzuki", + title: "Environmental Pioneer", + location: "Vancouver, BC", + category: "Environment", + description: + "For over 50 years, David has been Canada's environmental conscience. His work educated generations about climate change and inspired a global movement toward sustainable living.", + achievement: "Educated millions about environmental science through 'The Nature of Things'", + avatar: "/placeholder.svg?height=120&width=120", + }, +] + +builders_data.each do |attrs| + CanadianBuilder.find_or_create_by!(name: attrs[:name], government: government) do |builder| + builder.title = attrs[:title] + builder.location = attrs[:location] + builder.category = attrs[:category] + builder.description = attrs[:description] + builder.achievement = attrs[:achievement] + builder.avatar = attrs[:avatar] + builder.website = attrs[:website] + builder.slug = attrs[:name].parameterize + end +end + puts "Seeding Evidences..." puts "Done seeding"