#ruby-on-rails
#ruby-на-рельсах
Вопрос:
Я работаю над учебным пособием по Rails и в настоящее время работаю над разделом CRUD. Похоже, с Rails 3 на 4 произошли некоторые изменения в отношении действия создания. В руководстве используются Rails 3.x.x, а я использую Rails 4.1.2. Я попытался адаптировать свой контроллер posts, но получаю эту ошибку.
posts_controller.rb
class PostsController < ApplicationController
def index
@posts = Post.all
end
def show
@post = Post.find(params[:id])
end
def new
@post = Post.new
@category = Category.all
end
def create
@post = Post.new(params[:post])
if @post.save
redirect_to posts_path, :notice => "Your post has been saved"
else
render "new"
end
Category.create(category_params)
end
def edit
end
def update
end
def destroy
end
private
def category_params
params.require(:name).permit(:id)
end
def create
Post.create(post_params)
end
private
def post_params
params.require(:title, :body, :category_id, :author_id)
end
end
models/posts.rb
class Post < ActiveRecord::Base
belongs_to :category
end
Я могу сказать, что post contoller ошибочен, но ничего из того, что я пробовал, не сработало.
Обновить
Журнал сервера для действия создания
Started POST "/posts" for 127.0.0.1 at 2014-06-24 19:52:22 -0400
Processing by PostsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"w/ViBIFCFaaT1yIZaBkjWhjUjZ0LKXrT 9sOIN0c2q4=", "post"=>{"title"=>"teste", "body"=>"testest", "category_id"=>"4"}, "commit"=>"Add Post"}
Unpermitted parameters: utf8, authenticity_token, post, commit
[1m[36m (0.0ms)[0m [1mbegin transaction[0m
[1m[35mSQL (0.2ms)[0m INSERT INTO "posts" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2014-06-24 23:52:22.825483"], ["updated_at", "2014-06-24 23:52:22.825483"]]
[1m[36m (1.3ms)[0m [1mcommit transaction[0m
Redirected to http://domain:3000/posts
Unpermitted parameters: utf8, authenticity_token, post, commit
[1m[35m (0.0ms)[0m begin transaction
[1m[36mSQL (0.2ms)[0m [1mINSERT INTO "categories" ("created_at", "updated_at") VALUES (?, ?)[0m [["created_at", "2014-06-24 23:52:22.828618"], ["updated_at", "2014-06-24 23:52:22.828618"]]
[1m[35m (1.1ms)[0m commit transaction
Completed 302 Found in 6ms (ActiveRecord: 2.8ms)
Комментарии:
1. У вас определено два метода создания.
2. Да, это первое, что я предполагаю, неверно, наряду с тем фактом, что второе является частным.
3. Нет, у вас не может быть двух методов с одинаковым именем. Тот, который указан последним в файле, будет переопределять последний. Причина, по которой 2-й
create
вызывает ошибку, заключается в том, что он является частным и, следовательно, не существует для маршрутизатора в вашем приложении4. Нам нужно просмотреть параметры из журнала сервера. Чтобы увидеть, что получает контроллер.
Ответ №1:
У вас есть два метода создания, и один из них является частным. Так что вы, руби, не можете получить к нему доступ.
Редактировать: я добавил разрешение параметров. Похоже, вы не отправляете это удостоверение личности.
Ваш контроллер должен выглядеть следующим образом:
class PostsController < ApplicationController
def index
@posts = Post.all
end
def show
@post = Post.find(params[:id])
end
def new
@post = Post.new
@category = Category.all
end
def create
@post = Post.new(post_params)
if @post.save
redirect_to posts_path, :notice => "Your post has been saved"
else
render "new"
end
Category.create(category_params)
end
def edit
end
def update
end
def destroy
end
private
def category_params
params.require(:post).permit(:category_id)
end
def post_params
params.require(:post).permit(:title, :body, :category_id, :author_id)
end
end
Комментарии:
1. Спасибо. Я пробовал это раньше, и я получаю ошибку «ActiveModel::ForbiddenAttributesError», отслеживаемую
@post = Post.new(params[:post])
. Я также попытался изменить метод post_params наparams.require
с тем же результатом.2. Отредактированный контрольный пост.новый
3. Таким образом, это исправляет эту ошибку, но привело меня к ошибке
category_params
. Я предполагаю, что я требую:name, но отправляю только:id. Поэтому я изменил параметры категории на удалить.require(:name)
и оставил толькоparams.permit(:id)
. Теперь ошибки исчезли, и я перенаправлен обратно на:3000/posts, но, похоже, сохраненная запись пуста и содержит только идентификатор.4. Вставьте запрос параметров для этого действия в вопрос.
5. Я изменил методы на ваши параметры. Но вам нужно будет проверить свою форму. Вы не отправляете разрешенный вами идентификатор автора. Этого должно быть достаточно для ответа на этот вопрос.
Ответ №2:
Ваш контроллер в полном беспорядке. В нем есть два действия «создать» и два объявления «приватно». Используйте scaffold generator для создания контроллера для вас. Подробнее об этом читайте здесь: http://guides.rubyonrails.org/command_line.html
Комментарии:
1. Спасибо. В конце концов я все устрою, но я в самом начале, просто пытаюсь разобраться.
2. Неплохо бы поучиться на примере строительных лесов. Например:
rails g scaffold Post title:string body:text
.3. Спасибо, я обязательно это сделаю.
Ответ №3:
Сильные параметры
Вам нужно использовать strong params
в Rails 4:
#app/controllers/posts_controller.rb
Class PostsController < ApplicationController
def create
@post = Post.new(post_params)
@post.save
end
private
def post_params
parmas.require(:post).permit(:param1, :param2, :param3, :param4)
end
end
—
Маршруты
Во-вторых, вам нужно продумать resourceful
маршруты
Когда вы используете маршрутизацию в Rails, по умолчанию создаются маршруты вокруг определенных «ресурсов» (т.Е. Вокруг контроллеров / моделей). В принципе, маршруты, которые у вас есть, будут работать следующим образом:
#config/routes.rb
resources :posts
Возможно, вы уже знаете это, но по мере того, как вы будете следовать руководству, вы сможете увидеть, как работает механизм маршрутизации, позволяющий вам соответствующим образом прокладывать свои пути
Что вам также необходимо учитывать, так это то, что, как @san
уже указывалось, вам нужно убедиться, что у вас есть только один ресурсоемкий маршрут на контроллер (в настоящее время у вас есть два create
действия).