mirror of
https://github.com/danbee/my-images
synced 2025-03-04 08:49:05 +00:00
Add albums
This commit is contained in:
parent
750db7cf55
commit
6bbf9fcd73
58
app/assets/images/album.svg
Normal file
58
app/assets/images/album.svg
Normal file
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="256"
|
||||
height="256"
|
||||
viewBox="0 0 67.733332 67.733333"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
inkscape:version="1.3.2 (091e20e, 2023-11-25)"
|
||||
sodipodi:docname="album.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview1"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:zoom="1.8547559"
|
||||
inkscape:cx="-1.8870408"
|
||||
inkscape:cy="150.42411"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1387"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1" /><defs
|
||||
id="defs1" /><g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"><path
|
||||
id="rect1"
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.272"
|
||||
d="m 12.91127,6.6573004 c -3.3529062,0 -6.0523443,2.6994382 -6.0523443,6.0523446 v 34.194812 c 0,3.049461 2.235339,5.550874 5.1619593,5.979996 -0.01591,-0.17964 -0.02791,-0.360758 -0.02791,-0.544669 V 19.254539 c 0,-3.857255 3.607266,-7.161911 7.565389,-7.161911 h 32.681767 c 0.303632,0 0.59951,0.02959 0.890902,0.07235 C 52.856981,9.0695686 50.275077,6.6573004 47.106082,6.6573004 Z"
|
||||
sodipodi:nodetypes="ssscsssscss" /><rect
|
||||
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.272"
|
||||
id="rect2"
|
||||
width="46.299191"
|
||||
height="46.299191"
|
||||
x="15.298862"
|
||||
y="15.313577"
|
||||
ry="6.0521822" /><circle
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.31967;stroke-opacity:1"
|
||||
id="path3"
|
||||
cx="29.99498"
|
||||
cy="28.772318"
|
||||
r="5.7495732" /><path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 21.258978,55.737479 h 34.37896 c 0,0 -9.553836,-20.003863 -11.554753,-19.932004 -1.721418,0.06182 -4.850146,10.698848 -7.703169,10.698847 -2.14452,-1e-6 -3.066592,-3.138327 -5.706054,-2.995676 -2.639462,0.14265 -9.414984,12.228833 -9.414984,12.228833 z"
|
||||
id="path4"
|
||||
sodipodi:nodetypes="ccsszc" /></g></svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
27
app/controllers/albums_controller.rb
Normal file
27
app/controllers/albums_controller.rb
Normal file
@ -0,0 +1,27 @@
|
||||
class AlbumsController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
|
||||
def index
|
||||
@albums = @current_user.albums
|
||||
end
|
||||
|
||||
def create
|
||||
@album = Album.create(permitted_params)
|
||||
@current_user.albums << @album
|
||||
|
||||
redirect_to albums_path
|
||||
end
|
||||
|
||||
def destroy
|
||||
album = @current_user.albums.find(params[:id])
|
||||
album.destroy
|
||||
|
||||
redirect_to user_albums_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def permitted_params
|
||||
params.require(:album).permit(:user_id, :title)
|
||||
end
|
||||
end
|
||||
@ -1,5 +1,5 @@
|
||||
class HomeController < ApplicationController
|
||||
def index
|
||||
redirect_to user_images_path
|
||||
redirect_to albums_path
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
class ImagesController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :fetch_album
|
||||
|
||||
def index
|
||||
@images = @current_user.images
|
||||
@images = current_scope.images
|
||||
end
|
||||
|
||||
def show
|
||||
@ -14,19 +15,37 @@ class ImagesController < ApplicationController
|
||||
@current_user.images << @image
|
||||
TagImageJob.perform_later(image_id: @image.id)
|
||||
|
||||
redirect_to user_images_path
|
||||
redirect_for(@image)
|
||||
end
|
||||
|
||||
def destroy
|
||||
image = @current_user.images.find(params[:id])
|
||||
image.destroy
|
||||
|
||||
redirect_to user_images_path
|
||||
redirect_for(image)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redirect_for(image)
|
||||
if image.album.present?
|
||||
redirect_to album_images_path(image.album)
|
||||
else
|
||||
redirect_to images_path
|
||||
end
|
||||
end
|
||||
|
||||
def current_scope
|
||||
@album || @current_user
|
||||
end
|
||||
|
||||
def fetch_album
|
||||
if params[:album_id].present?
|
||||
@album = @current_user.albums.find(params[:album_id])
|
||||
end
|
||||
end
|
||||
|
||||
def permitted_params
|
||||
params.require(:image).permit(:user_id, :image)
|
||||
params.require(:image).permit(:user_id, :album_id, :image)
|
||||
end
|
||||
end
|
||||
|
||||
@ -20,12 +20,12 @@ const config = () => ({
|
||||
|
||||
export default {
|
||||
createTag: (tag) => {
|
||||
return axios.post(`/user/images/${imageId()}/tags`, { tag }, config());
|
||||
return axios.post(`/images/${imageId()}/tags`, { tag }, config());
|
||||
},
|
||||
|
||||
deleteTag: (tag) => {
|
||||
return axios.delete(
|
||||
`/user/images/${imageId()}/tags/${encodeURIComponent(tag)}`,
|
||||
`/images/${imageId()}/tags/${encodeURIComponent(tag)}`,
|
||||
config()
|
||||
);
|
||||
}
|
||||
|
||||
7
app/models/album.rb
Normal file
7
app/models/album.rb
Normal file
@ -0,0 +1,7 @@
|
||||
class Album < ApplicationRecord
|
||||
validates :title, presence: true
|
||||
|
||||
belongs_to :user
|
||||
|
||||
has_many :images
|
||||
end
|
||||
@ -4,4 +4,5 @@ class Image < ActiveRecord::Base
|
||||
validates :image, presence: true
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :album
|
||||
end
|
||||
|
||||
@ -2,6 +2,7 @@ class User < ActiveRecord::Base
|
||||
dragonfly_accessor :avatar
|
||||
|
||||
has_many :images
|
||||
has_many :albums
|
||||
|
||||
def self.find_or_create_from_auth(auth)
|
||||
find_by(auth.slice(:provider, :uid)) || create_from_auth(auth)
|
||||
|
||||
29
app/views/albums/index.html.erb
Normal file
29
app/views/albums/index.html.erb
Normal file
@ -0,0 +1,29 @@
|
||||
<% content_for :title do %>
|
||||
<h1>My Albums</h1>
|
||||
<% end %>
|
||||
|
||||
<h2>Albums</h2>
|
||||
|
||||
<ul class="images">
|
||||
<% @albums.each do |album| %>
|
||||
<li>
|
||||
<%= link_to album_images_path(album), class: :album do %>
|
||||
<% if album.images.any? %>
|
||||
<%= image_tag(album.images.first.image.thumb('200x200#').url) %>
|
||||
<% else %>
|
||||
<%= image_tag(asset_path("album.svg")) %>
|
||||
<% end %>
|
||||
|
||||
<%= album.title %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<h2>Create New Album</h2>
|
||||
|
||||
<%= simple_form_for @albums.new do |f| %>
|
||||
<%= f.input :user_id, as: :hidden %>
|
||||
<%= f.input :title %>
|
||||
<%= f.submit %>
|
||||
<% end %>
|
||||
@ -3,7 +3,7 @@
|
||||
<%= render "tags/tags", image: image, tags: image.tags %>
|
||||
|
||||
<div class="new-tag-form">
|
||||
<%= form_tag user_image_tags_path(image),
|
||||
<%= form_tag image_tags_path(image),
|
||||
method: :post,
|
||||
data: { action: "tags#create" } do %>
|
||||
<%= text_field_tag :tag, nil, data: { target: "tags.tag" } %>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
data-controller="tag">
|
||||
<span data-target="tag.name"><%= tag %></span>
|
||||
<%= link_to "×".html_safe,
|
||||
user_image_tag_path(@image, tag),
|
||||
image_tag_path(@image, tag),
|
||||
method: :delete,
|
||||
data: { action: "click->tag#delete" },
|
||||
class: "delete-tag" %>
|
||||
|
||||
@ -1,13 +1,17 @@
|
||||
<% content_for :title do %>
|
||||
<h1>My Images</h1>
|
||||
<h1><%= link_to "My Albums", albums_path %></h1>
|
||||
<% end %>
|
||||
|
||||
<% if @album.present? %>
|
||||
<h2><%= @album.title %></h2>
|
||||
<% end %>
|
||||
|
||||
<ul class="images">
|
||||
<% @images.each do |image| %>
|
||||
<li>
|
||||
<%= link_to image_tag(image.image.thumb('200x200#').url),
|
||||
user_image_path(image), class: :image %><br>
|
||||
<%= link_to 'Delete', user_image_path(image),
|
||||
image_path(image), class: :image %><br>
|
||||
<%= link_to 'Delete', image_path(image),
|
||||
method: :delete, data: { confirm: 'Are you sure?' } %>
|
||||
</li>
|
||||
<% end %>
|
||||
@ -15,8 +19,9 @@
|
||||
|
||||
<h2>Upload New Image</h2>
|
||||
|
||||
<%= simple_form_for [@current_user, @images.new] do |f| %>
|
||||
<%= simple_form_for @images.new do |f| %>
|
||||
<%= f.input :user_id, as: :hidden %>
|
||||
<%= f.input :album_id, as: :hidden %>
|
||||
<%= f.input :image, as: :file %>
|
||||
<%= f.submit %>
|
||||
<% end %>
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
<% content_for :title do %>
|
||||
<h1><%= link_to "My Images", user_images_path %></h1>
|
||||
<h1><%= link_to "My Albums", albums_path %></h1>
|
||||
<% if @image.album.present? %>
|
||||
→
|
||||
<%= link_to @image.album.title, album_images_path(@image.album) %>
|
||||
<% end %>
|
||||
→
|
||||
<%= @image.image.name %>
|
||||
<% end %>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
data-controller="tag">
|
||||
<span data-target="tag.name"><%= tag %></span>
|
||||
<%= link_to "×".html_safe,
|
||||
user_image_tag_path(image, tag),
|
||||
image_tag_path(image, tag),
|
||||
data: { action: "click->tag#delete" },
|
||||
class: "delete-tag" %>
|
||||
</li>
|
||||
|
||||
@ -4,9 +4,11 @@ Rails.application.routes.draw do
|
||||
resource :session, only: %i[new destroy]
|
||||
get "/auth/:provider/callback", to: "sessions#create", as: :create_session
|
||||
|
||||
resource :user, only: [] do
|
||||
resources :images, only: %i[index show create destroy] do
|
||||
resources :tags, only: %i[create destroy]
|
||||
end
|
||||
resources :images, only: %i[index show create destroy] do
|
||||
resources :tags, only: %i[create destroy]
|
||||
end
|
||||
|
||||
resources :albums, only: %i[index create destroy] do
|
||||
resources :images, only: %i[index]
|
||||
end
|
||||
end
|
||||
|
||||
11
db/migrate/20240324003804_create_albums.rb
Normal file
11
db/migrate/20240324003804_create_albums.rb
Normal file
@ -0,0 +1,11 @@
|
||||
class CreateAlbums < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
create_table :albums do |t|
|
||||
t.string :title
|
||||
t.text :description
|
||||
t.belongs_to :user
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
5
db/migrate/20240324010757_add_album_to_images.rb
Normal file
5
db/migrate/20240324010757_add_album_to_images.rb
Normal file
@ -0,0 +1,5 @@
|
||||
class AddAlbumToImages < ActiveRecord::Migration[7.0]
|
||||
def change
|
||||
add_belongs_to :images, :album
|
||||
end
|
||||
end
|
||||
31
db/schema.rb
generated
31
db/schema.rb
generated
@ -10,22 +10,31 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.0].define(version: 2018_08_26_163510) do
|
||||
ActiveRecord::Schema[7.0].define(version: 2024_03_24_010757) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
create_table "albums", force: :cascade do |t|
|
||||
t.string "title"
|
||||
t.text "description"
|
||||
t.bigint "user_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["user_id"], name: "index_albums_on_user_id"
|
||||
end
|
||||
|
||||
create_table "delayed_jobs", force: :cascade do |t|
|
||||
t.integer "priority", default: 0, null: false
|
||||
t.integer "attempts", default: 0, null: false
|
||||
t.text "handler", null: false
|
||||
t.text "last_error"
|
||||
t.datetime "run_at"
|
||||
t.datetime "locked_at"
|
||||
t.datetime "failed_at"
|
||||
t.datetime "run_at", precision: nil
|
||||
t.datetime "locked_at", precision: nil
|
||||
t.datetime "failed_at", precision: nil
|
||||
t.string "locked_by"
|
||||
t.string "queue"
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
t.datetime "created_at", precision: nil
|
||||
t.datetime "updated_at", precision: nil
|
||||
t.index ["priority", "run_at"], name: "delayed_jobs_priority"
|
||||
end
|
||||
|
||||
@ -33,9 +42,11 @@ ActiveRecord::Schema[7.0].define(version: 2018_08_26_163510) do
|
||||
t.integer "user_id"
|
||||
t.string "image_uid"
|
||||
t.string "image_name"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.string "tags", default: [], array: true
|
||||
t.bigint "album_id"
|
||||
t.index ["album_id"], name: "index_images_on_album_id"
|
||||
end
|
||||
|
||||
create_table "users", force: :cascade do |t|
|
||||
@ -44,8 +55,8 @@ ActiveRecord::Schema[7.0].define(version: 2018_08_26_163510) do
|
||||
t.string "name"
|
||||
t.string "provider"
|
||||
t.string "uid"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
t.string "avatar_uid"
|
||||
end
|
||||
|
||||
|
||||
7
spec/models/album_spec.rb
Normal file
7
spec/models/album_spec.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require "rails_helper"
|
||||
|
||||
describe Album do
|
||||
it { is_expected.to validate_presence_of(:title) }
|
||||
it { is_expected.to belong_to(:user) }
|
||||
it { is_expected.to have_many(:images) }
|
||||
end
|
||||
@ -3,6 +3,7 @@ require "rails_helper"
|
||||
describe Image do
|
||||
it { is_expected.to validate_presence_of(:image) }
|
||||
it { is_expected.to belong_to(:user) }
|
||||
it { is_expected.to belong_to(:album) }
|
||||
|
||||
it "should not be valid without an image" do
|
||||
image = Image.new
|
||||
|
||||
@ -2,4 +2,5 @@ require "rails_helper"
|
||||
|
||||
describe User do
|
||||
it { is_expected.to have_many(:images) }
|
||||
it { is_expected.to have_many(:albums) }
|
||||
end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user