Tôi có các mô hình Dish
và Comment
như dưới đây trong ứng dụng API Rails 5.1 của tôi - mã repo here. Tôi cần trợ giúp với việc thêm Comment
mới vào Dish
.PUT với đối tượng lồng nhau
bài
class Dish < ApplicationRecord
has_many :comments
end
Comment
class Comment < ApplicationRecord
belongs_to :dish
end
bài Serializer (sử dụng ActiveModel Seriazlier)
class DishSerializer < ActiveModel::Serializer
attributes :id, :name, :image, :category, :label, :price, :featured, :description, :created_at
has_many :comments
end
Comment Serializer
class CommentSerializer < ActiveModel::Serializer
attributes :id, :rating, :comment, :author, :date
def date
object.created_at
end
end
bài viết khiển - ray mặc định giàn giáo
class DishesController < ApplicationController
before_action :set_dish, only: [:show, :update, :destroy]
# GET /dishes
def index
@dishes = Dish.all
render json: @dishes
end
# GET /dishes/1
def show
render json: @dish
end
# POST /dishes
def create
@dish = Dish.new(dish_params)
if @dish.save
render json: @dish, status: :created, location: @dish
else
render json: @dish.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /dishes/1
def update
# byebug
if @dish.update(dish_params)
render json: @dish
else
render json: @dish.errors, status: :unprocessable_entity
end
end
# DELETE /dishes/1
def destroy
@dish.destroy
end
private
# Use callbacks to share common setup or constraints between actions.
def set_dish
@dish = Dish.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def dish_params
params.require(:dish).permit(:name, :image, :category, :label, :price, :featured, :description)
end
end
Comment khiển - ray mặc định giàn giáo
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :update, :destroy]
# GET /comments
def index
@comments = Comment.all
render json: @comments
end
# GET /comments/1
def show
render json: @comment
end
# POST /comments
def create
@comment = Comment.new(comment_params)
if @comment.save
render json: @comment, status: :created, location: @comment
else
render json: @comment.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /comments/1
def update
if @comment.update(comment_params)
render json: @comment
else
render json: @comment.errors, status: :unprocessable_entity
end
end
# DELETE /comments/1
def destroy
@comment.destroy
end
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
@comment = Comment.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def comment_params
params.require(:comment).permit(:rating, :comment, :author)
end
end
Issue
Khi người dùng truy cập /dishes/:id
và thêm một bình luận cho một món ăn thông qua các ứng dụng front-end (góc 2), comment
là push to mảng bình luận hiện nay và tôi đang gọi PUT /dishes:id
với đối tượng dish
lồng với hiện có comments
và nhận xét mới. Tuy nhiên, comment
mới không được lưu bởi đường ray - không trả về lỗi, thay vì trả về đối tượng dish
. Tuy nhiên, tôi thấy Unpermitted parameters: :id, :created_at
trong bảng điều khiển rails s
. Làm thế nào để tôi có được đường ray để lưu nhận xét mới?
Trang (dishes/9
) từ nơi tôi thêm nhận xét vào một món ăn trông giống như bên dưới ở phía khách hàng Góc cạnh.
Rails server log
Về phía đường ray, dưới đây là những gì tôi nhìn thấy trong params
- Tôi thấy nhận xét mới - {"author"=>"JANE7777", "rating"=>3, "comment"=>"COMMENT7777", "date"=>"2017-11-12T12:58:12.555Z"}
trong đó.
Started PUT "/dishes/9" for 127.0.0.1 at 2017-11-12 18:28:12 +0530
Processing by DishesController#update as HTML
Parameters: {"id"=>"9", "name"=>"Uthappizza", "image"=>"images/uthappizza.png", "category"=>"mains", "label"=>"Hot", "price"=>"4.99", "featured"=>true, "description"=>"A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.", "created_at"=>"2017-11-01T04:30:09.407Z", "comments"=>[{"id"=>46, "rating"=>5, "comment"=>"Imagine all the eatables, living in conFusion!", "author"=>"John Lemon", "date"=>"2012-10-16T17:57:28.556Z"}, {"id"=>47, "rating"=>4, "comment"=>"Sends anyone to heaven, I wish I could get my mother-in-law to eat it!", "author"=>"Paul McVites", "date"=>"2014-09-05T17:57:28.556Z"}, {"id"=>48, "rating"=>3, "comment"=>"Eat it, just eat it!", "author"=>"Michael Jaikishan", "date"=>"2015-02-13T17:57:28.556Z"}, {"id"=>49, "rating"=>4, "comment"=>"Ultimate, Reaching for the stars!", "author"=>"Ringo Starry", "date"=>"2013-12-02T17:57:28.556Z"}, {"id"=>50, "rating"=>2, "comment"=>"It's your birthday, we're gonna party!", "author"=>"25 Cent", "date"=>"2011-12-02T17:57:28.556Z"}, {"id"=>51, "rating"=>4, "comment"=>"great dish", "author"=>"Jogesh", "date"=>"2017-10-30T05:03:39.656Z"}, {"author"=>"JANE7777", "rating"=>3, "comment"=>"COMMENT7777", "date"=>"2017-11-12T12:58:12.555Z"}], "dish"=>{"id"=>"9", "name"=>"Uthappizza", "image"=>"images/uthappizza.png", "category"=>"mains", "label"=>"Hot", "price"=>"4.99", "featured"=>true, "description"=>"A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.", "created_at"=>"2017-11-01T04:30:09.407Z"}}
Dish Load (1.0ms) SELECT "dishes".* FROM "dishes" WHERE "dishes"."id" = $1 LIMIT $2 [["id", 9], ["LIMIT", 1]]
[25, 34] in C:/apps/railsApi/app/controllers/dishes_controller.rb
25: end
26:
27: # PATCH/PUT /dishes/1
28: def update
29: byebug
=> 30: if @dish.update(dish_params)
31: render json: @dish
32: else
33: render json: @dish.errors, status: :unprocessable_entity
34: end
(byebug) params
<ActionController::Parameters {"id"=>"9", "name"=>"Uthappizza", "image"=>"images/uthappizza.png", "category"=>"mains", "label"=>"Hot", "price"=>"4.99", "featured"=>true, "description"=>"A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.", "created_at"=>"2017-11-01T04:30:09.407Z", "comments"=>[{"id"=>46, "rating"=>5, "comment"=>"Imagine all the eatables, living in conFusion!", "author"=>"John Lemon", "date"=>"2012-10-16T17:57:28.556Z"}, {"id"=>47, "rating"=>4, "comment"=>"Sends anyone to heaven, I wish I could get my mother-in-law to eat it!", "author"=>"Paul McVites", "date"=>"2014-09-05T17:57:28.556Z"}, {"id"=>48, "rating"=>3, "comment"=>"Eat it, just eat it!", "author"=>"Michael Jaikishan", "date"=>"2015-02-13T17:57:28.556Z"}, {"id"=>49, "rating"=>4, "comment"=>"Ultimate, Reaching for the stars!", "author"=>"Ringo Starry", "date"=>"2013-12-02T17:57:28.556Z"}, {"id"=>50, "rating"=>2, "comment"=>"It's your birthday, we're gonna party!", "author"=>"25 Cent", "date"=>"2011-12-02T17:57:28.556Z"}, {"id"=>51, "rating"=>4, "comment"=>"great dish", "author"=>"Jogesh", "date"=>"2017-10-30T05:03:39.656Z"}, {"author"=>"JANE7777", "rating"=>3, "comment"=>"COMMENT7777", "date"=>"2017-11-12T12:58:12.555Z"}], "controller"=>"dishes", "action"=>"update", "dish"=>{"id"=>9, "name"=>"Uthappizza", "image"=>"images/uthappizza.png", "category"=>"mains", "label"=>"Hot", "price"=>"4.99", "featured"=>true, "description"=>"A unique combination of Indian Uthappam (pancake) and Italian pizza, topped with Cerignola olives, ripe vine cherry tomatoes, Vidalia onion, Guntur chillies and Buffalo Paneer.", "created_at"=>"2017-11-01T04:30:09.407Z"}} permitted: false>
(byebug) c
Unpermitted parameters: :id, :created_at
(0.0ms) BEGIN
(0.0ms) COMMIT
[active_model_serializers] Comment Load (0.0ms) SELECT "comments".* FROM "comments" WHERE "comments"."dish_id" = $1 [["dish_id", 9]]
[active_model_serializers] Rendered DishSerializer with ActiveModelSerializers::Adapter::Attributes (31.29ms)
Completed 200 OK in 1901725ms (Views: 37.5ms | ActiveRecord: 5.0ms)
mô hình Client-side
Mô hình Dish
có Comment[]
là một trong những thành viên. Khi một bình luận mới được thêm vào thông qua các hình thức comment
được đẩy đến dish.comments
mảng trước khi gửi các đối tượng Dish
đến Rails API back-end.
Comment
mô hình ở phía client
export class Comment {
rating: number;
comment: string;
author: string;
date: string;
}
Post
mô hình ở phía client
import { Comment } from './comment';
export class Dish {
id: number;
name: string;
image: string;
category: string;
label: string;
price: string;
featured: boolean;
description: string;
comments: Comment[];
}
bạn có kiểm tra các vấn đề CSRF và lỗi hiển thị liên quan đến các thông số chưa được gửi không? PUT là để cập nhật, POST là để tạo. Bạn có thể thử sử dụng một tài nguyên lồng nhau hoặc nếu bạn muốn tiếp tục sử dụng push thêm accepts_nested_attributes cho trong dish.rb cho comment.rb. Cố gắng viết một trường hợp thử nghiệm nhỏ thay vì thử lại hoặc thử nghiệm từ giao diện người dùng để giúp hiểu hoặc chạy mã trong bảng điều khiển byebug. – Sairam
Tôi sử dụng 'rack-cors' và đã định cấu hình - yêu cầu GET của tôi hoạt động tốt !! – user3206440
Tại sao bạn không tạo ý kiến hành động riêng biệt # tạo? Giải pháp của bạn là hacky. Ngay cả khi nó sẽ hoạt động, nó không phải là một cái gì đó bạn thực sự cần tìm kiếm. – AntonTkachov