feat: add friendly_id for cities and weather arts
- Integrate 'friendly_id' gem for sluggable functionality in City model - Create ActiveAdmin resources for managing cities and weather arts - Implement controller logic for cities - Add database migrations for cities and weather arts creation - Seed database with sample data for testing - Create initial test cases for controllers and models This commit enhances the application's URL handling by allowing friendly URLs for cities and weather arts. The addition of ActiveAdmin resources facilitates easier management through a web interface.
This commit is contained in:
parent
8517905b68
commit
e5743a5e3f
1
.idea/today_ai_weather.iml
generated
1
.idea/today_ai_weather.iml
generated
@ -69,6 +69,7 @@
|
||||
<orderEntry type="library" scope="PROVIDED" name="et-orbi (v1.2.11, mise: 3.3.5) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="formtastic (v5.0.0, mise: 3.3.5) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="formtastic_i18n (v0.7.0, mise: 3.3.5) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="friendly_id (v5.5.1, mise: 3.3.5) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="fugit (v1.11.1, mise: 3.3.5) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="globalid (v1.2.1, mise: 3.3.5) [gem]" level="application" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="has_scope (v0.8.2, mise: 3.3.5) [gem]" level="application" />
|
||||
|
1
Gemfile
1
Gemfile
@ -43,6 +43,7 @@ gem "thruster", require: false
|
||||
# gem "image_processing", "~> 1.2"
|
||||
gem 'devise', '~> 4.9'
|
||||
gem 'activeadmin', '~> 3.2'
|
||||
gem 'friendly_id', '~> 5.5'
|
||||
|
||||
group :development, :test do
|
||||
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
|
||||
|
@ -135,6 +135,8 @@ GEM
|
||||
formtastic (5.0.0)
|
||||
actionpack (>= 6.0.0)
|
||||
formtastic_i18n (0.7.0)
|
||||
friendly_id (5.5.1)
|
||||
activerecord (>= 4.0.0)
|
||||
fugit (1.11.1)
|
||||
et-orbi (~> 1, >= 1.2.11)
|
||||
raabro (~> 1.4)
|
||||
@ -428,6 +430,7 @@ DEPENDENCIES
|
||||
cssbundling-rails
|
||||
debug
|
||||
devise (~> 4.9)
|
||||
friendly_id (~> 5.5)
|
||||
jbuilder
|
||||
jsbundling-rails
|
||||
kamal
|
||||
|
54
app/admin/cities.rb
Normal file
54
app/admin/cities.rb
Normal file
@ -0,0 +1,54 @@
|
||||
ActiveAdmin.register City do
|
||||
controller do
|
||||
def find_resource
|
||||
scoped_collection.friendly.find(params[:id])
|
||||
end
|
||||
end
|
||||
|
||||
# See permitted parameters documentation:
|
||||
# https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters
|
||||
#
|
||||
# Uncomment all parameters which should be permitted for assignment
|
||||
#
|
||||
permit_params :name, :country, :latitude, :longitude, :active, :priority, :timezone, :region, :last_weather_fetch, :last_image_generation, :slug
|
||||
#
|
||||
# or
|
||||
#
|
||||
# permit_params do
|
||||
# permitted = [:name, :country, :latitude, :longitude, :active, :priority, :timezone, :region, :last_weather_fetch, :last_image_generation, :slug]
|
||||
# permitted << :other if params[:action] == 'create' && current_user.admin?
|
||||
# permitted
|
||||
# end
|
||||
|
||||
index do
|
||||
selectable_column
|
||||
id_column
|
||||
column :name
|
||||
column :slug
|
||||
column :latitude
|
||||
column :longitude
|
||||
column :active
|
||||
column :created_at
|
||||
actions
|
||||
end
|
||||
|
||||
filter :name
|
||||
filter :active
|
||||
|
||||
form do |f|
|
||||
f.inputs do
|
||||
f.input :active
|
||||
f.input :name
|
||||
f.input :country, as: :String
|
||||
f.input :latitude
|
||||
f.input :longitude
|
||||
f.input :priority
|
||||
f.input :timezone
|
||||
f.input :region
|
||||
f.input :last_weather_fetch
|
||||
f.input :last_image_generation
|
||||
end
|
||||
f.actions
|
||||
end
|
||||
|
||||
end
|
78
app/admin/weather_arts.rb
Normal file
78
app/admin/weather_arts.rb
Normal file
@ -0,0 +1,78 @@
|
||||
ActiveAdmin.register WeatherArt do
|
||||
|
||||
# See permitted parameters documentation:
|
||||
# https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters
|
||||
#
|
||||
# Uncomment all parameters which should be permitted for assignment
|
||||
#
|
||||
# permit_params :city_id, :weather_date, :description, :temperature, :feeling_temp, :humidity, :wind_scale, :wind_speed, :precipitation, :pressure, :visibility, :cloud, :prompt
|
||||
#
|
||||
# or
|
||||
#
|
||||
# permit_params do
|
||||
# permitted = [:city_id, :weather_date, :description, :temperature, :feeling_temp, :humidity, :wind_scale, :wind_speed, :precipitation, :pressure, :visibility, :cloud, :prompt]
|
||||
# permitted << :other if params[:action] == 'create' && current_user.admin?
|
||||
# permitted
|
||||
# end
|
||||
permit_params :city_id, :weather_date, :description, :temperature,
|
||||
:feeling_temp, :humidity, :wind_scale, :wind_speed,
|
||||
:precipitation, :pressure, :visibility, :cloud,
|
||||
:prompt, :image
|
||||
|
||||
remove_filter :image_attachment, :image_blob
|
||||
|
||||
index do
|
||||
selectable_column
|
||||
id_column
|
||||
column :city
|
||||
column :weather_date
|
||||
column :description
|
||||
column :temperature
|
||||
column :image do |weather_art|
|
||||
image_tag(weather_art.image, size: '100x100') if weather_art.image.attached?
|
||||
end
|
||||
actions
|
||||
end
|
||||
|
||||
show do
|
||||
attributes_table do
|
||||
row :city
|
||||
row :weather_date
|
||||
row :description
|
||||
row :temperature
|
||||
row :feeling_temp
|
||||
row :humidity
|
||||
row :wind_scale
|
||||
row :wind_speed
|
||||
row :precipitation
|
||||
row :pressure
|
||||
row :visibility
|
||||
row :cloud
|
||||
row :prompt
|
||||
row :image do |weather_art|
|
||||
image_tag(weather_art.image) if weather_art.image.attached?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
form do |f|
|
||||
f.inputs do
|
||||
f.input :city
|
||||
f.input :weather_date
|
||||
f.input :description
|
||||
f.input :temperature
|
||||
f.input :feeling_temp
|
||||
f.input :humidity
|
||||
f.input :wind_scale
|
||||
f.input :wind_speed
|
||||
f.input :precipitation
|
||||
f.input :pressure
|
||||
f.input :visibility
|
||||
f.input :cloud
|
||||
f.input :prompt
|
||||
f.input :image, as: :file
|
||||
end
|
||||
f.actions
|
||||
end
|
||||
|
||||
end
|
8
app/controllers/cities_controller.rb
Normal file
8
app/controllers/cities_controller.rb
Normal file
@ -0,0 +1,8 @@
|
||||
class CitiesController < ApplicationController
|
||||
def index
|
||||
@cities = City.friendly.find(params[:id])
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
end
|
4
app/controllers/home_controller.rb
Normal file
4
app/controllers/home_controller.rb
Normal file
@ -0,0 +1,4 @@
|
||||
class HomeController < ApplicationController
|
||||
def index
|
||||
end
|
||||
end
|
4
app/controllers/weather_arts_controller.rb
Normal file
4
app/controllers/weather_arts_controller.rb
Normal file
@ -0,0 +1,4 @@
|
||||
class WeatherArtsController < ApplicationController
|
||||
def show
|
||||
end
|
||||
end
|
2
app/helpers/cities_helper.rb
Normal file
2
app/helpers/cities_helper.rb
Normal file
@ -0,0 +1,2 @@
|
||||
module CitiesHelper
|
||||
end
|
2
app/helpers/home_helper.rb
Normal file
2
app/helpers/home_helper.rb
Normal file
@ -0,0 +1,2 @@
|
||||
module HomeHelper
|
||||
end
|
2
app/helpers/weather_arts_helper.rb
Normal file
2
app/helpers/weather_arts_helper.rb
Normal file
@ -0,0 +1,2 @@
|
||||
module WeatherArtsHelper
|
||||
end
|
@ -3,4 +3,9 @@ class AdminUser < ApplicationRecord
|
||||
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
||||
devise :database_authenticatable,
|
||||
:recoverable, :rememberable, :validatable
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
# 列出你想要允许搜索的属性
|
||||
%w[created_at email id updated_at]
|
||||
end
|
||||
end
|
||||
|
23
app/models/city.rb
Normal file
23
app/models/city.rb
Normal file
@ -0,0 +1,23 @@
|
||||
class City < ApplicationRecord
|
||||
extend FriendlyId
|
||||
friendly_id :name, use: :slugged
|
||||
|
||||
has_many :weather_arts, dependent: :destroy
|
||||
|
||||
validates :name, presence: true
|
||||
validates :latitude, presence: true
|
||||
validates :longitude, presence: true
|
||||
|
||||
def should_generate_new_friendly_id?
|
||||
name_changed? || super
|
||||
end
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
[ "weather_arts" ]
|
||||
end
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
["active", "country", "created_at", "id", "id_value", "last_image_generation", "last_weather_fetch", "latitude", "longitude", "name", "priority", "region", "slug", "timezone", "updated_at"]
|
||||
end
|
||||
|
||||
end
|
16
app/models/weather_art.rb
Normal file
16
app/models/weather_art.rb
Normal file
@ -0,0 +1,16 @@
|
||||
class WeatherArt < ApplicationRecord
|
||||
belongs_to :city
|
||||
|
||||
has_one_attached :image
|
||||
|
||||
validates :weather_date, presence: true
|
||||
validates :city_id, presence: true
|
||||
|
||||
def self.ransackable_associations(auth_object = nil)
|
||||
["city", "image_attachment", "image_blob"]
|
||||
end
|
||||
|
||||
def self.ransackable_attributes(auth_object = nil)
|
||||
[ "city_id", "cloud", "created_at", "description", "feeling_temp", "humidity", "id", "id_value", "precipitation", "pressure", "prompt", "temperature", "updated_at", "visibility", "weather_date", "wind_scale", "wind_speed" ]
|
||||
end
|
||||
end
|
2
app/views/cities/index.html.erb
Normal file
2
app/views/cities/index.html.erb
Normal file
@ -0,0 +1,2 @@
|
||||
<h1>Cities#index</h1>
|
||||
<p>Find me in app/views/cities/index.html.erb</p>
|
2
app/views/cities/show.html.erb
Normal file
2
app/views/cities/show.html.erb
Normal file
@ -0,0 +1,2 @@
|
||||
<h1>Cities#show</h1>
|
||||
<p>Find me in app/views/cities/show.html.erb</p>
|
2
app/views/home/index.html.erb
Normal file
2
app/views/home/index.html.erb
Normal file
@ -0,0 +1,2 @@
|
||||
<h1>Home#index</h1>
|
||||
<p>Find me in app/views/home/index.html.erb</p>
|
2
app/views/weather_arts/show.html.erb
Normal file
2
app/views/weather_arts/show.html.erb
Normal file
@ -0,0 +1,2 @@
|
||||
<h1>WeatherArts#show</h1>
|
||||
<p>Find me in app/views/weather_arts/show.html.erb</p>
|
@ -4,12 +4,12 @@ ActiveAdmin.setup do |config|
|
||||
# Set the title that is displayed on the main layout
|
||||
# for each of the active admin pages.
|
||||
#
|
||||
config.site_title = "Today Ai Weather"
|
||||
config.site_title = "Today Ai Weather Admin"
|
||||
|
||||
# Set the link url for the title. For example, to take
|
||||
# users to your main site. Defaults to no link.
|
||||
#
|
||||
# config.site_title_link = "/"
|
||||
config.site_title_link = "/"
|
||||
|
||||
# Set an optional image to be displayed for the header
|
||||
# instead of a string (overrides :site_title)
|
||||
|
107
config/initializers/friendly_id.rb
Normal file
107
config/initializers/friendly_id.rb
Normal file
@ -0,0 +1,107 @@
|
||||
# FriendlyId Global Configuration
|
||||
#
|
||||
# Use this to set up shared configuration options for your entire application.
|
||||
# Any of the configuration options shown here can also be applied to single
|
||||
# models by passing arguments to the `friendly_id` class method or defining
|
||||
# methods in your model.
|
||||
#
|
||||
# To learn more, check out the guide:
|
||||
#
|
||||
# http://norman.github.io/friendly_id/file.Guide.html
|
||||
|
||||
FriendlyId.defaults do |config|
|
||||
# ## Reserved Words
|
||||
#
|
||||
# Some words could conflict with Rails's routes when used as slugs, or are
|
||||
# undesirable to allow as slugs. Edit this list as needed for your app.
|
||||
config.use :reserved
|
||||
|
||||
config.reserved_words = %w[new edit index session login logout users admin
|
||||
stylesheets assets javascripts images]
|
||||
|
||||
# This adds an option to treat reserved words as conflicts rather than exceptions.
|
||||
# When there is no good candidate, a UUID will be appended, matching the existing
|
||||
# conflict behavior.
|
||||
|
||||
# config.treat_reserved_as_conflict = true
|
||||
|
||||
# ## Friendly Finders
|
||||
#
|
||||
# Uncomment this to use friendly finders in all models. By default, if
|
||||
# you wish to find a record by its friendly id, you must do:
|
||||
#
|
||||
# MyModel.friendly.find('foo')
|
||||
#
|
||||
# If you uncomment this, you can do:
|
||||
#
|
||||
# MyModel.find('foo')
|
||||
#
|
||||
# This is significantly more convenient but may not be appropriate for
|
||||
# all applications, so you must explicitly opt-in to this behavior. You can
|
||||
# always also configure it on a per-model basis if you prefer.
|
||||
#
|
||||
# Something else to consider is that using the :finders addon boosts
|
||||
# performance because it will avoid Rails-internal code that makes runtime
|
||||
# calls to `Module.extend`.
|
||||
#
|
||||
# config.use :finders
|
||||
#
|
||||
# ## Slugs
|
||||
#
|
||||
# Most applications will use the :slugged module everywhere. If you wish
|
||||
# to do so, uncomment the following line.
|
||||
#
|
||||
# config.use :slugged
|
||||
#
|
||||
# By default, FriendlyId's :slugged addon expects the slug column to be named
|
||||
# 'slug', but you can change it if you wish.
|
||||
#
|
||||
# config.slug_column = 'slug'
|
||||
#
|
||||
# By default, slug has no size limit, but you can change it if you wish.
|
||||
#
|
||||
# config.slug_limit = 255
|
||||
#
|
||||
# When FriendlyId can not generate a unique ID from your base method, it appends
|
||||
# a UUID, separated by a single dash. You can configure the character used as the
|
||||
# separator. If you're upgrading from FriendlyId 4, you may wish to replace this
|
||||
# with two dashes.
|
||||
#
|
||||
# config.sequence_separator = '-'
|
||||
#
|
||||
# Note that you must use the :slugged addon **prior** to the line which
|
||||
# configures the sequence separator, or else FriendlyId will raise an undefined
|
||||
# method error.
|
||||
#
|
||||
# ## Tips and Tricks
|
||||
#
|
||||
# ### Controlling when slugs are generated
|
||||
#
|
||||
# As of FriendlyId 5.0, new slugs are generated only when the slug field is
|
||||
# nil, but if you're using a column as your base method can change this
|
||||
# behavior by overriding the `should_generate_new_friendly_id?` method that
|
||||
# FriendlyId adds to your model. The change below makes FriendlyId 5.0 behave
|
||||
# more like 4.0.
|
||||
# Note: Use(include) Slugged module in the config if using the anonymous module.
|
||||
# If you have `friendly_id :name, use: slugged` in the model, Slugged module
|
||||
# is included after the anonymous module defined in the initializer, so it
|
||||
# overrides the `should_generate_new_friendly_id?` method from the anonymous module.
|
||||
#
|
||||
# config.use :slugged
|
||||
# config.use Module.new {
|
||||
# def should_generate_new_friendly_id?
|
||||
# slug.blank? || <your_column_name_here>_changed?
|
||||
# end
|
||||
# }
|
||||
#
|
||||
# FriendlyId uses Rails's `parameterize` method to generate slugs, but for
|
||||
# languages that don't use the Roman alphabet, that's not usually sufficient.
|
||||
# Here we use the Babosa library to transliterate Russian Cyrillic slugs to
|
||||
# ASCII. If you use this, don't forget to add "babosa" to your Gemfile.
|
||||
#
|
||||
# config.use Module.new {
|
||||
# def normalize_friendly_id(text)
|
||||
# text.to_slug.normalize! :transliterations => [:russian, :latin]
|
||||
# end
|
||||
# }
|
||||
end
|
@ -1,4 +1,20 @@
|
||||
Rails.application.routes.draw do
|
||||
root "home#index"
|
||||
|
||||
resources :cities, only: [ :index, :show ] do
|
||||
resources :weather_arts, only: [ :show ]
|
||||
end
|
||||
|
||||
# namespace :admin do
|
||||
# resources :cities
|
||||
# resources :weather_arts
|
||||
# root to: "cities#index"
|
||||
# end
|
||||
|
||||
get "weather_arts/show"
|
||||
get "cities/index"
|
||||
get "cities/show"
|
||||
get "home/index"
|
||||
devise_for :admin_users, ActiveAdmin::Devise.config
|
||||
ActiveAdmin.routes(self)
|
||||
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
|
||||
|
18
db/migrate/20250119022826_create_cities.rb
Normal file
18
db/migrate/20250119022826_create_cities.rb
Normal file
@ -0,0 +1,18 @@
|
||||
class CreateCities < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :cities do |t|
|
||||
t.string :name
|
||||
t.string :country
|
||||
t.float :latitude
|
||||
t.float :longitude
|
||||
t.boolean :active
|
||||
t.integer :priority
|
||||
t.string :timezone
|
||||
t.string :region
|
||||
t.datetime :last_weather_fetch
|
||||
t.datetime :last_image_generation
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
6
db/migrate/20250119032146_add_slug_to_cities.rb
Normal file
6
db/migrate/20250119032146_add_slug_to_cities.rb
Normal file
@ -0,0 +1,6 @@
|
||||
class AddSlugToCities < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
add_column :cities, :slug, :string
|
||||
add_index :cities, :slug, unique: true
|
||||
end
|
||||
end
|
21
db/migrate/20250119032158_create_friendly_id_slugs.rb
Normal file
21
db/migrate/20250119032158_create_friendly_id_slugs.rb
Normal file
@ -0,0 +1,21 @@
|
||||
MIGRATION_CLASS =
|
||||
if ActiveRecord::VERSION::MAJOR >= 5
|
||||
ActiveRecord::Migration["#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"]
|
||||
else
|
||||
ActiveRecord::Migration
|
||||
end
|
||||
|
||||
class CreateFriendlyIdSlugs < MIGRATION_CLASS
|
||||
def change
|
||||
create_table :friendly_id_slugs do |t|
|
||||
t.string :slug, null: false
|
||||
t.integer :sluggable_id, null: false
|
||||
t.string :sluggable_type, limit: 50
|
||||
t.string :scope
|
||||
t.datetime :created_at
|
||||
end
|
||||
add_index :friendly_id_slugs, [:sluggable_type, :sluggable_id]
|
||||
add_index :friendly_id_slugs, [:slug, :sluggable_type], length: {slug: 140, sluggable_type: 50}
|
||||
add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], length: {slug: 70, sluggable_type: 50, scope: 70}, unique: true
|
||||
end
|
||||
end
|
21
db/migrate/20250119032316_create_weather_arts.rb
Normal file
21
db/migrate/20250119032316_create_weather_arts.rb
Normal file
@ -0,0 +1,21 @@
|
||||
class CreateWeatherArts < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
create_table :weather_arts do |t|
|
||||
t.references :city, null: false, foreign_key: true
|
||||
t.date :weather_date
|
||||
t.string :description
|
||||
t.decimal :temperature
|
||||
t.decimal :feeling_temp
|
||||
t.decimal :humidity
|
||||
t.string :wind_scale
|
||||
t.decimal :wind_speed
|
||||
t.decimal :precipitation
|
||||
t.decimal :pressure
|
||||
t.decimal :visibility
|
||||
t.decimal :cloud
|
||||
t.text :prompt
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,57 @@
|
||||
# This migration comes from active_storage (originally 20170806125915)
|
||||
class CreateActiveStorageTables < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
# Use Active Record's configured type for primary and foreign keys
|
||||
primary_key_type, foreign_key_type = primary_and_foreign_key_types
|
||||
|
||||
create_table :active_storage_blobs, id: primary_key_type do |t|
|
||||
t.string :key, null: false
|
||||
t.string :filename, null: false
|
||||
t.string :content_type
|
||||
t.text :metadata
|
||||
t.string :service_name, null: false
|
||||
t.bigint :byte_size, null: false
|
||||
t.string :checksum
|
||||
|
||||
if connection.supports_datetime_with_precision?
|
||||
t.datetime :created_at, precision: 6, null: false
|
||||
else
|
||||
t.datetime :created_at, null: false
|
||||
end
|
||||
|
||||
t.index [ :key ], unique: true
|
||||
end
|
||||
|
||||
create_table :active_storage_attachments, id: primary_key_type do |t|
|
||||
t.string :name, null: false
|
||||
t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type
|
||||
t.references :blob, null: false, type: foreign_key_type
|
||||
|
||||
if connection.supports_datetime_with_precision?
|
||||
t.datetime :created_at, precision: 6, null: false
|
||||
else
|
||||
t.datetime :created_at, null: false
|
||||
end
|
||||
|
||||
t.index [ :record_type, :record_id, :name, :blob_id ], name: :index_active_storage_attachments_uniqueness, unique: true
|
||||
t.foreign_key :active_storage_blobs, column: :blob_id
|
||||
end
|
||||
|
||||
create_table :active_storage_variant_records, id: primary_key_type do |t|
|
||||
t.belongs_to :blob, null: false, index: false, type: foreign_key_type
|
||||
t.string :variation_digest, null: false
|
||||
|
||||
t.index [ :blob_id, :variation_digest ], name: :index_active_storage_variant_records_uniqueness, unique: true
|
||||
t.foreign_key :active_storage_blobs, column: :blob_id
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def primary_and_foreign_key_types
|
||||
config = Rails.configuration.generators
|
||||
setting = config.options[config.orm][:primary_key_type]
|
||||
primary_key_type = setting || :primary_key
|
||||
foreign_key_type = setting || :bigint
|
||||
[ primary_key_type, foreign_key_type ]
|
||||
end
|
||||
end
|
81
db/schema.rb
generated
81
db/schema.rb
generated
@ -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_01_18_163460) do
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_01_19_032348) do
|
||||
create_table "active_admin_comments", force: :cascade do |t|
|
||||
t.string "namespace"
|
||||
t.text "body"
|
||||
@ -25,6 +25,34 @@ ActiveRecord::Schema[8.0].define(version: 2025_01_18_163460) do
|
||||
t.index ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource"
|
||||
end
|
||||
|
||||
create_table "active_storage_attachments", force: :cascade do |t|
|
||||
t.string "name", null: false
|
||||
t.string "record_type", null: false
|
||||
t.bigint "record_id", null: false
|
||||
t.bigint "blob_id", null: false
|
||||
t.datetime "created_at", null: false
|
||||
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
|
||||
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
|
||||
end
|
||||
|
||||
create_table "active_storage_blobs", force: :cascade do |t|
|
||||
t.string "key", null: false
|
||||
t.string "filename", null: false
|
||||
t.string "content_type"
|
||||
t.text "metadata"
|
||||
t.string "service_name", null: false
|
||||
t.bigint "byte_size", null: false
|
||||
t.string "checksum"
|
||||
t.datetime "created_at", null: false
|
||||
t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
|
||||
end
|
||||
|
||||
create_table "active_storage_variant_records", force: :cascade do |t|
|
||||
t.bigint "blob_id", null: false
|
||||
t.string "variation_digest", null: false
|
||||
t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
|
||||
end
|
||||
|
||||
create_table "admin_users", force: :cascade do |t|
|
||||
t.string "email", default: "", null: false
|
||||
t.string "encrypted_password", default: "", null: false
|
||||
@ -36,4 +64,55 @@ ActiveRecord::Schema[8.0].define(version: 2025_01_18_163460) do
|
||||
t.index ["email"], name: "index_admin_users_on_email", unique: true
|
||||
t.index ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true
|
||||
end
|
||||
|
||||
create_table "cities", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "country"
|
||||
t.float "latitude"
|
||||
t.float "longitude"
|
||||
t.boolean "active"
|
||||
t.integer "priority"
|
||||
t.string "timezone"
|
||||
t.string "region"
|
||||
t.datetime "last_weather_fetch"
|
||||
t.datetime "last_image_generation"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "slug"
|
||||
t.index ["slug"], name: "index_cities_on_slug", unique: true
|
||||
end
|
||||
|
||||
create_table "friendly_id_slugs", force: :cascade do |t|
|
||||
t.string "slug", null: false
|
||||
t.integer "sluggable_id", null: false
|
||||
t.string "sluggable_type", limit: 50
|
||||
t.string "scope"
|
||||
t.datetime "created_at"
|
||||
t.index ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true
|
||||
t.index ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type"
|
||||
t.index ["sluggable_type", "sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_type_and_sluggable_id"
|
||||
end
|
||||
|
||||
create_table "weather_arts", force: :cascade do |t|
|
||||
t.integer "city_id", null: false
|
||||
t.date "weather_date"
|
||||
t.string "description"
|
||||
t.decimal "temperature"
|
||||
t.decimal "feeling_temp"
|
||||
t.decimal "humidity"
|
||||
t.string "wind_scale"
|
||||
t.decimal "wind_speed"
|
||||
t.decimal "precipitation"
|
||||
t.decimal "pressure"
|
||||
t.decimal "visibility"
|
||||
t.decimal "cloud"
|
||||
t.text "prompt"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["city_id"], name: "index_weather_arts_on_city_id"
|
||||
end
|
||||
|
||||
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
|
||||
add_foreign_key "weather_arts", "cities"
|
||||
end
|
||||
|
37
db/seeds.rb
37
db/seeds.rb
@ -7,4 +7,39 @@
|
||||
# ["Action", "Comedy", "Drama", "Horror"].each do |genre_name|
|
||||
# MovieGenre.find_or_create_by!(name: genre_name)
|
||||
# end
|
||||
AdminUser.create!(email: 'admin@example.com', password: 'password', password_confirmation: 'password') if Rails.env.development?
|
||||
AdminUser.create!(email: 'admin@example.com', password: 'password', password_confirmation: 'password') if Rails.env.development?
|
||||
|
||||
guangzhou = City.create!(
|
||||
name: 'Guangzhou',
|
||||
country: 'China',
|
||||
latitude: 23.1291,
|
||||
longitude: 113.2644,
|
||||
active: true,
|
||||
priority: 50,
|
||||
timezone: 'Asia/Shanghai',
|
||||
region: 'Asia',
|
||||
last_weather_fetch: 10.hours.ago,
|
||||
last_image_generation: 10.hours.ago
|
||||
)
|
||||
|
||||
guangzhou_weather_art = WeatherArt.create!(
|
||||
city: guangzhou,
|
||||
weather_date: Date.today,
|
||||
description: 'Sunny with some clouds',
|
||||
temperature: 28.5,
|
||||
feeling_temp: 30.2,
|
||||
humidity: 65,
|
||||
wind_scale: "3级",
|
||||
wind_speed: 15,
|
||||
precipitation: 0,
|
||||
pressure: 1013,
|
||||
visibility: 10,
|
||||
cloud: 30,
|
||||
prompt: "A sunny day in Guangzhou with modern buildings under blue sky and white clouds, digital art style"
|
||||
)
|
||||
|
||||
guangzhou_weather_art.image.attach(
|
||||
io: File.open("db/seeds/images/sample-guangzhou-weather-art.png"),
|
||||
filename: "sample-guangzhou-weather-art.png",
|
||||
content_type: "image/png"
|
||||
)
|
BIN
db/seeds/images/sample-guangzhou-weather-art.png
Normal file
BIN
db/seeds/images/sample-guangzhou-weather-art.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.9 MiB |
13
test/controllers/cities_controller_test.rb
Normal file
13
test/controllers/cities_controller_test.rb
Normal file
@ -0,0 +1,13 @@
|
||||
require "test_helper"
|
||||
|
||||
class CitiesControllerTest < ActionDispatch::IntegrationTest
|
||||
test "should get index" do
|
||||
get cities_index_url
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "should get show" do
|
||||
get cities_show_url
|
||||
assert_response :success
|
||||
end
|
||||
end
|
8
test/controllers/home_controller_test.rb
Normal file
8
test/controllers/home_controller_test.rb
Normal file
@ -0,0 +1,8 @@
|
||||
require "test_helper"
|
||||
|
||||
class HomeControllerTest < ActionDispatch::IntegrationTest
|
||||
test "should get index" do
|
||||
get home_index_url
|
||||
assert_response :success
|
||||
end
|
||||
end
|
8
test/controllers/weather_arts_controller_test.rb
Normal file
8
test/controllers/weather_arts_controller_test.rb
Normal file
@ -0,0 +1,8 @@
|
||||
require "test_helper"
|
||||
|
||||
class WeatherArtsControllerTest < ActionDispatch::IntegrationTest
|
||||
test "should get show" do
|
||||
get weather_arts_show_url
|
||||
assert_response :success
|
||||
end
|
||||
end
|
29
test/fixtures/cities.yml
vendored
Normal file
29
test/fixtures/cities.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
#one:
|
||||
# name: MyString
|
||||
# country: MyString
|
||||
# slug: MyString
|
||||
# latitude: 1.5
|
||||
# longitude: 1.5
|
||||
# active: false
|
||||
# priority: 1
|
||||
# timezone: MyString
|
||||
# population: 1
|
||||
# region: MyString
|
||||
# last_weather_fetch: 2025-01-19 10:28:26
|
||||
# last_image_generation: 2025-01-19 10:28:26
|
||||
#
|
||||
#two:
|
||||
# name: MyString
|
||||
# country: MyString
|
||||
# slug: MyString
|
||||
# latitude: 1.5
|
||||
# longitude: 1.5
|
||||
# active: false
|
||||
# priority: 1
|
||||
# timezone: MyString
|
||||
# population: 1
|
||||
# region: MyString
|
||||
# last_weather_fetch: 2025-01-19 10:28:26
|
||||
# last_image_generation: 2025-01-19 10:28:26
|
31
test/fixtures/weather_arts.yml
vendored
Normal file
31
test/fixtures/weather_arts.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
city: one
|
||||
weather_date: 2025-01-19
|
||||
description: MyString
|
||||
temperature: 9.99
|
||||
feeling_temp: 9.99
|
||||
humidity: 9.99
|
||||
wind_scale: MyString
|
||||
wind_speed: 9.99
|
||||
precipitation: 9.99
|
||||
pressure: 9.99
|
||||
visibility: 9.99
|
||||
cloud: 9.99
|
||||
prompt: MyText
|
||||
|
||||
two:
|
||||
city: two
|
||||
weather_date: 2025-01-19
|
||||
description: MyString
|
||||
temperature: 9.99
|
||||
feeling_temp: 9.99
|
||||
humidity: 9.99
|
||||
wind_scale: MyString
|
||||
wind_speed: 9.99
|
||||
precipitation: 9.99
|
||||
pressure: 9.99
|
||||
visibility: 9.99
|
||||
cloud: 9.99
|
||||
prompt: MyText
|
7
test/models/city_test.rb
Normal file
7
test/models/city_test.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require "test_helper"
|
||||
|
||||
class CityTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
7
test/models/weather_art_test.rb
Normal file
7
test/models/weather_art_test.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require "test_helper"
|
||||
|
||||
class WeatherArtTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
Loading…
Reference in New Issue
Block a user