请原谅我的英语不完美。
我希望能够使用一个theme
创建一个subcategory
(并且子类别具有一个主题),并将此theme
链接到多个categories
。我希望我可以做Theme.first.categories
或Category.first.themes
。
在主题表中,我只保存名称和子弹。在子类别表中,我保存了描述,页面标题等,因为每个类别将具有名称相同但描述不同的主题。
例如,我可以有两个类别,例如“法语到英语”和“意大利语到中文”。这些类别都将具有一个名为“科学”的主题,但具有不同的描述。
当前,我可以创建一个主题,但只能创建一个类别。例如,如果我选择两个类别,则会出现错误:can't modify frozen Hash
。
theme.rb:
class Theme < ApplicationRecord
has_one(:subcategory, dependent: :destroy)
has_many(:categories, through: :subcategory)
accepts_nested_attributes_for :subcategory
end
subcategory.rb:
class Subcategory < ApplicationRecord
belongs_to(:category)
belongs_to(:theme)
end
category.rb:
class Category < ApplicationRecord
has_many(:subcategories, dependent: :destroy)
has_many(:themes, through: :subcategories)
end
schema.rb:
create_table "themes", force: :cascade do |t|
t.string "name", null: false
t.string "slug"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "subcategories", force: :cascade do |t|
t.text "description"
t.string "page_title"
t.string "meta_description"
t.string "h1_title"
t.bigint "category_id"
t.bigint "theme_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["category_id"], name: "index_subcategories_on_category_id"
t.index ["theme_id"], name: "index_subcategories_on_theme_id"
end
create_table "categories", force: :cascade do |t|
t.string "name", null: false
t.datetime "created_at"
t.datetime "updated_at"
t.string "slug"
t.text "description"
t.string "page_title"
t.string "meta_description"
t.string "h1_title"
t.string "source_language"
t.string "target_language"
end
themes_controller.rb:
# frozen_string_literal: true
module Admin
class ThemesController < AdminController
load_and_authorize_resource except: :update
before_action(:load_categories, only: %i[new edit])
before_action(:load_theme, only: :update)
def index
@themes = Theme.all.to_a
end
def new
@theme.build_subcategory
end
def create
@theme = Theme.new(theme_params)
if @theme.save
redirect_to(admin_themes_url, notice: 'Theme successfully created')
else
render(:new)
end
end
def edit
end
def update
if @theme.update(theme_params)
redirect_to(admin_themes_url, notice: 'Theme successfully edited')
else
render(:edit)
end
end
def destroy
@theme.destroy
redirect_to(admin_themes_url, notice: 'Theme successfully deleted')
end
private
def theme_params
params.require(:theme).permit(
:id,
:name,
:slug,
subcategory_attributes: %i[description h1_title page_title meta_description],
category_ids: [],
)
end
def load_categories
@categories = Category.all.to_a
end
def load_theme
@theme = Theme.find_by(slug: params[:id])
end
end
end
和我的表单:
= simple_form_for([:admin, @theme]) do |f|
= f.input(:name, autofocus: true)
= f.simple_fields_for :subcategory_attributes, @theme.subcategory do |s|
= s.input(:h1_title)
= s.input(:description)
= s.input(:page_title)
= s.input(:meta_description)
= f.input(:category_ids, collection: @categories.map { |cat| [cat.name, cat.id] }, as: :check_boxes, wrapper: :vertical_radio_and_checkboxes)
= f.button(:submit , class: 'btn btn-primary')
日志:
0:39:39 server.1 | Started POST "/admin/themes" for ::1 at 2019-01-11 10:39:39 +0100
10:39:39 server.1 | Processing by Admin::ThemesController#create as HTML
10:39:39 server.1 | Parameters: {"utf8"=>"✓", "authenticity_token"=>"6p2oxZvOlFJHYvAeYbkjjOrGGk8Y5GrnFOTBuQEmxTcMIhgfK32N2/ZGabLYmoW0pHiUaX6hVqb/EeuTgbr55g==", "theme"=>{"name"=>"rerezre", "subcategory_attributes"=>{"h1_title"=>"reez", "description"=>"rezer", "page_title"=>"rezrez", "meta_description"=>"rezerez"}, "category_ids"=>["", "1", "2"]}, "commit"=>"Créer un(e) Theme"}
10:39:39 server.1 | User Load (1.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 7], ["LIMIT", 1]]
10:39:39 server.1 | ↳ app/controllers/application_controller.rb:93
10:39:39 server.1 | Category Load (0.8ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" IN ($1, $2) [["id", 1], ["id", 2]]
10:39:39 server.1 | ↳ /Users/robin/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1.1/lib/active_record/log_subscriber.rb:98
10:39:39 server.1 | (0.3ms) BEGIN
10:39:39 server.1 | ↳ /Users/robin/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1.1/lib/active_record/log_subscriber.rb:98
10:39:39 server.1 | (0.3ms) COMMIT
10:39:39 server.1 | ↳ /Users/robin/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1.1/lib/active_record/log_subscriber.rb:98
10:39:39 server.1 | CACHE Category Load (0.0ms) SELECT "categories".* FROM "categories" WHERE "categories"."id" IN ($1, $2) [["id", 1], ["id", 2]]
10:39:39 server.1 | ↳ app/controllers/admin/themes_controller.rb:18
10:39:39 server.1 | (0.2ms) BEGIN
10:39:39 server.1 | ↳ app/controllers/admin/themes_controller.rb:18
10:39:39 server.1 | (0.1ms) COMMIT
10:39:39 server.1 | ↳ app/controllers/admin/themes_controller.rb:18
10:39:39 server.1 | (0.1ms) BEGIN
10:39:39 server.1 | ↳ app/controllers/admin/themes_controller.rb:19
10:39:39 server.1 | Category Exists (0.5ms) SELECT 1 AS one FROM "categories" WHERE LOWER("categories"."name") = LOWER($1) AND "categories"."id" != $2 LIMIT $3 [["name", "Français à anglais"], ["id", 1], ["LIMIT", 1]]
10:39:39 server.1 | ↳ app/controllers/admin/themes_controller.rb:19
10:39:39 server.1 | Category Exists (0.5ms) SELECT 1 AS one FROM "categories" WHERE LOWER("categories"."name") = LOWER($1) AND "categories"."id" != $2 LIMIT $3 [["name", "Italien à chinois"], ["id", 2], ["LIMIT", 1]]
10:39:39 server.1 | ↳ app/controllers/admin/themes_controller.rb:19
10:39:39 server.1 | Theme Create (0.7ms) INSERT INTO "themes" ("name", "slug", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["name", "rerezre"], ["slug", "rerezre"], ["created_at", "2019-01-11 09:39:39.193694"], ["updated_at", "2019-01-11 09:39:39.193694"]]
10:39:39 server.1 | ↳ app/controllers/admin/themes_controller.rb:19
10:39:39 server.1 | Subcategory Create (0.5ms) INSERT INTO "subcategories" ("description", "page_title", "meta_description", "h1_title", "category_id", "theme_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["description", "rezer"], ["page_title", "rezrez"], ["meta_description", "rezerez"], ["h1_title", "reez"], ["category_id", 2], ["theme_id", 24], ["created_at", "2019-01-11 09:39:39.196215"], ["updated_at", "2019-01-11 09:39:39.196215"]]
10:39:39 server.1 | ↳ app/controllers/admin/themes_controller.rb:19
10:39:39 server.1 | Category Exists (0.3ms) SELECT 1 AS one FROM "categories" WHERE LOWER("categories"."name") = LOWER($1) AND "categories"."id" != $2 LIMIT $3 [["name", "Français à anglais"], ["id", 1], ["LIMIT", 1]]
10:39:39 server.1 | ↳ app/controllers/admin/themes_controller.rb:19
10:39:39 server.1 | (0.2ms) ROLLBACK
10:39:39 server.1 | ↳ app/controllers/admin/themes_controller.rb:19
10:39:39 server.1 | Completed 500 Internal Server Error in 32ms (ActiveRecord: 7.0ms)
10:39:39 server.1 |
10:39:39 server.1 |
10:39:39 server.1 | can't modify frozen Hash excluded from capture: Not configured to send/capture in environment 'development'
10:39:39 server.1 |
10:39:39 server.1 | FrozenError (can't modify frozen Hash):
10:39:39 server.1 |
10:39:39 server.1 | app/controllers/admin/themes_controller.rb:19:in `create'
我知道如果我想做自己想做的事,关系就会有问题,但是我不知道该怎么办。
请有人可以帮助我吗?
答案 0 :(得分:1)
这里有一个概念上的问题。
由于Theme
与Subcategory
具有一对一的关系,而Category
与Theme
具有一对多的关系Category
和{{1}之间的传递关系}不能多对多。为此,Theme
必须与Subcategory
至少具有一对多关系。
换句话说: 每个主题只有一个子类别,每个子类别只有一个类别,因此每个主题到子类别都只有一个类别。 如果您希望某个主题具有多个类别(通过子类别),则应允许该主题具有多个子类别。