| @@ -88,7 +88,7 @@ class PostsController < ApplicationController | |||||
| original_created_from = params[:original_created_from] | original_created_from = params[:original_created_from] | ||||
| original_created_before = params[:original_created_before] | original_created_before = params[:original_created_before] | ||||
| post = Post.new(title:, url:, thumbnail_base: '', uploaded_user: current_user, | |||||
| post = Post.new(title:, url:, thumbnail_base: nil, uploaded_user: current_user, | |||||
| original_created_from:, original_created_before:) | original_created_from:, original_created_before:) | ||||
| post.thumbnail.attach(thumbnail) | post.thumbnail.attach(thumbnail) | ||||
| if post.save | if post.save | ||||
| @@ -0,0 +1,4 @@ | |||||
| class TagSimilarity < ApplicationRecord | |||||
| belongs_to :tag, class_name: 'Tag', foreign_key: 'tag_id' | |||||
| belongs_to :target_tag, class_name: 'Tag', foreign_key: 'target_tag_id' | |||||
| end | |||||
| @@ -0,0 +1,27 @@ | |||||
| class MakeThumbnailBaseNullableInPosts < ActiveRecord::Migration[7.0] | |||||
| def up | |||||
| change_column_null :posts, :thumbnail_base, true | |||||
| execute <<~SQL | |||||
| UPDATE | |||||
| posts | |||||
| SET | |||||
| thumbnail_base = NULL | |||||
| WHERE | |||||
| thumbnail_base = '' | |||||
| SQL | |||||
| end | |||||
| def down | |||||
| execute <<~SQL | |||||
| UPDATE | |||||
| posts | |||||
| SET | |||||
| thumbnail_base = '' | |||||
| WHERE | |||||
| thumbnail_base IS NULL | |||||
| SQL | |||||
| change_column_null :posts, :thumbnail_base, false | |||||
| end | |||||
| end | |||||
| @@ -10,7 +10,7 @@ | |||||
| # | # | ||||
| # It's strongly recommended that you check this file into your version control system. | # It's strongly recommended that you check this file into your version control system. | ||||
| ActiveRecord::Schema[8.0].define(version: 2025_12_29_022100) do | |||||
| ActiveRecord::Schema[8.0].define(version: 2025_12_30_143400) do | |||||
| create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| | create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| | ||||
| t.string "name", null: false | t.string "name", null: false | ||||
| t.string "record_type", null: false | t.string "record_type", null: false | ||||
| @@ -86,7 +86,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_12_29_022100) do | |||||
| create_table "posts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| | create_table "posts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| | ||||
| t.string "title", null: false | t.string "title", null: false | ||||
| t.string "url", limit: 2000, null: false | t.string "url", limit: 2000, null: false | ||||
| t.string "thumbnail_base", limit: 2000, null: false | |||||
| t.string "thumbnail_base", limit: 2000 | |||||
| t.bigint "parent_id" | t.bigint "parent_id" | ||||
| t.bigint "uploaded_user_id" | t.bigint "uploaded_user_id" | ||||
| t.datetime "created_at", null: false | t.datetime "created_at", null: false | ||||
| @@ -0,0 +1,28 @@ | |||||
| namespace :tag_similarity do | |||||
| desc '関聯タグ・テーブル作成' | |||||
| task calc: :environment do | |||||
| dot = -> a, b { (a.keys & b.keys).sum { |k| a[k] * b[k] } } | |||||
| norm = -> v { Math.sqrt(v.values.sum { |e| e * e }) } | |||||
| cos = -> a, b do | |||||
| na = norm.(a) | |||||
| nb = norm.(b) | |||||
| if na.zero? || nb.zero? | |||||
| 0.0 | |||||
| else | |||||
| dot.(a, b) / na / nb | |||||
| end | |||||
| end | |||||
| tags = Tag.includes(:posts).to_a | |||||
| tags.each_with_index do |tag, i| | |||||
| existence_of_posts = tag.posts.index_with(1) | |||||
| ((i + 1)...tags.size).each do |j| | |||||
| target_tag = tags[j] | |||||
| existence_of_target_posts = target_tag.posts.index_with(1) | |||||
| TagSimilarity.find_or_initialize_by(tag:, target_tag:).tap { |ts| | |||||
| ts.cos = cos.(existence_of_posts, existence_of_target_posts) | |||||
| }.save! | |||||
| end | |||||
| end | |||||
| end | |||||
| end | |||||
| @@ -49,7 +49,7 @@ namespace :nico do | |||||
| unless post | unless post | ||||
| title = datum['title'] | title = datum['title'] | ||||
| url = "https://www.nicovideo.jp/watch/#{ datum['code'] }" | url = "https://www.nicovideo.jp/watch/#{ datum['code'] }" | ||||
| thumbnail_base = fetch_thumbnail.(url) || '' rescue '' | |||||
| thumbnail_base = fetch_thumbnail.(url) rescue nil | |||||
| post = Post.new(title:, url:, thumbnail_base:, uploaded_user: nil) | post = Post.new(title:, url:, thumbnail_base:, uploaded_user: nil) | ||||
| if thumbnail_base.present? | if thumbnail_base.present? | ||||
| post.thumbnail.attach( | post.thumbnail.attach( | ||||