2017-11-12 39 views
7

Tôi có các mô hình DishComment 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. enter image description here

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 DishComment[] 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[]; 
} 
+0

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

+0

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

+0

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

Trả lời

0

tôi muốn khuyên bạn sử dụng bộ điều khiển nhận xét và hình thành một tuyến đường lồng nhau để được yên tĩnh.

Trước hết, hãy gửi yêu cầu, bao gồm dish_id đến/nhận xét. Bạn đang cố tạo Comment, không cập nhật Dish.

Thứ hai, hình thành các tuyến đường lồng nhau: /bát đĩa /: dish_id/comments

Dưới đây là hướng dẫn để các nguồn lực làm tổ như thế này: http://guides.rubyonrails.org/routing.html#nested-resources

Lý do lỗi của bạn là bạn đã phá vỡ dự kiến cấu trúc tham số. Đối với PUT, các thông số của bạn phải là:

{ 
    id: <record to update>, 
    dish: { 
     name: “blah”, 
     comments: [{...},{...}] 
    } 
} 

Một lần nữa, tôi thực sự khuyên bạn không nên PUT nếu bạn chỉ muốn thêm nhận xét. Ví dụ: ở trên sẽ được mong muốn để thay thế tất cả các ý kiến ​​trên Dish! Nếu bạn đang tạo bản ghi, hãy tạo bản ghi đó, không cập nhật bản ghi đó cho phụ huynh.

Nếu bạn muốn cập nhật Món ăn khi đã thêm nhận xét mới, bạn có thể thêm gọi lại vào mô hình nhận xét khi tạo hoặc thực hiện trong tác vụ bộ điều khiển tạo chú thích.

Các vấn đề liên quan