#ruby-on-rails #ruby
#ruby-on-rails #ruby
Вопрос:
Я новичок в RoR, и я работаю над приложением Blog и внедряю категории для статей. Но у меня проблема — когда я создаю любую статью с некоторыми категориями («спорт», «фильм» или любой другой) Я получаю ошибки проверки
- Category must exist
- Category can't be blank
Но у меня есть рабочий выпадающий список или категории (этот помощник):
def categories
category =
["Sport",
"Movie",
"Art",
"Nature",
"Exotic"]
category.each do |categ|
my_category = "#{categ}"
end
return category
end
И вот фрагмент кода моего файла article.new.html.erb:
<p>
<%= f.label :category %><br>
<%= f.select :category, categories,
prompt: "Choose your category" %>
</p>
Также вот моя схема БД, где присутствуют поля категорий:
create_table "articles", force: :cascade do |t|
t.string "title"
t.text "text"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "pic"
t.string "photo_file_name"
t.string "photo_content_type"
t.bigint "photo_file_size"
t.datetime "photo_updated_at"
t.string "music_file_name"
t.string "music_content_type"
t.bigint "music_file_size"
t.datetime "music_updated_at"
t.string "movie_file_name"
t.string "movie_content_type"
t.bigint "movie_file_size"
t.datetime "movie_updated_at"
t.string "category_id"
end
create_table "categories", force: :cascade do |t|
t.string "name"
t.text "desc"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "comments", force: :cascade do |t|
t.string "commenter"
t.text "body"
t.bigint "article_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["article_id"], name: "index_comments_on_article_id"
end
create_table "subscribers", force: :cascade do |t|
t.string "f_name"
t.string "l_name"
t.string "email"
t.string "country"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "users", force: :cascade do |t|
t.string "userid"
t.string "email"
t.string "password_digest"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "admin", default: false
end
add_foreign_key "comments", "articles"
end
И вот мои модели:
class Article < ApplicationRecord
belongs_to :category
has_many :comments, dependent: :destroy
validates :title, presence: true, length: {minimum: 3}
validates :text, presence: true, length: {minimum: 3}
validates :category_id, presence: true
end
class Category < ApplicationRecord
has_many :articles
end
Также это мой контроллер статей:
class ArticlesController < ApplicationController
before_action :admin_authorize, :except => [:index, :show, :search]
def index
@articles = Article.includes(:category).order("created_at DESC")
if params[:category].blank?
@articles = Article.all.order("created_at DESC")
else
@category_id = Category.find_by(name: params[:category]).id
@articles = Article.where(category_id: @category_id).order("created_at DESC")
end
end
def new
@article = Article.new
@categories = Category.all.map{|c| [c.name, c.id]}
end
def show
@article = Article.find(params[:id])
end
def create
@article = Article.new(article_params)
@article.category_id = params[:category_id]
respond_to do |format|
if @article.save
format.html { redirect_to @article, notice: "Article was successfully created!" }
format.json { render :show, status: :created, location: @article }
else
format.html { render :new}
format.json {render json: @article.errors, status: :unprocessable_entity}
end
end
end
def edit
@article = Article.find(params[:id])
@categories = Category.all.map{|c| [ c.name, c.id ] }
end
def search
if params[:search].blank?
@articles = Article.all
else
@articles = Article.search(params)
end
end
def update
@article = Article.find(params[:id])
@article.category_id = params[:category_id]
if @article.update(article_params)
redirect_to @article
else
render 'edit'
end
end
def destroy
@article = Article.find(params[:id])
@article.destroy
redirect_to articles_path
end
private
def article_params
params.require(:article).permit(:title, :text, :search, :music, :movie, :photo)
end
def find_article
@article = Article.find(params[:id])
end
end
Заранее спасибо!!
Комментарии:
1. Эти категории существуют в базе данных, верно?
2. Да, я добавил их через консоль
3. @OrkoElvis Посмотрите журналы сервера, возможно, вам не хватает некоторых обязательных параметров.
4. с помощью консоли?
Ответ №1:
Вы забыли category_id
в своих разрешенных параметрах:
def article_params
params.require(:article).permit(:title, :text, :search, :music, :movie, :photo, :category_id)
end
Вам также необходимо изменить свой помощник по выбору на отправку, category_id
а не category
в запросе POST.
Теперь, с помощью вашего categories
помощника, вы не отправляете никакого идентификатора категории в select
выпадающем списке, только некоторые имена «category», которые не привязаны ни к каким Category
экземплярам.
Вы можете исправить это select
следующим образом и удалить своего помощника:
<p>
<%= f.label :category %><br>
<%= f.select :category_id, Category.all.collect{|c| [c.name, c.id]},
prompt: "Choose your category" %>
</p>
Комментарии:
1. @OrkoElvis Да, вы правы! Вы не отправляете идентификатор категории в
select
раскрывающемся списке. Я обновил свой ответ.2. Все то же самое (
3. @OrkoElvis Если у вас их нет
Category
в db, у вас всегда будут эти ошибки. Как говорится,Category
должно существовать для созданияArticle
из-за ассоциацииbelongs_to :category
4. Как я мог бы добавить их в db?
5. @OrkoElvis Запустите
rails console
в своем терминале и добавьте туда несколько категорий:Category.create(name: "My name", desc: "Whatever blah blah")