如何使用另一个对象的 id 调用对象的 create 方法? [英] How can I invoke the create method of an object with another object's id?

查看:35
本文介绍了如何使用另一个对象的 id 调用对象的 create 方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试建立一个带有评论功能的画廊.考虑有 3 个类:相册、照片、评论.这些对象的关系是相册有很多照片,照片有很多评论.

每条评论都是注册用户留下的,因此评论对象中有comment_text、user_id和photo_id(指评论所属的照片).

我正在尝试在每张照片的展示"视图下创建一个评论表单.下面是一些 Controller 和 Show 视图:

controllers/photos_controller.rb

class PhotosController <应用控制器...高清秀@photo = Photo.find(params[:id])@new_comment = @photo.comments.build 如果 user_signed_in?@comment_items = @photo.comments.paginate(page: params[:page])结尾...结尾

views/photos/show.html.erb

<代码>...<%= form_for @new_comment, html: {method: :post} do |c|%><div class="row"><div class="span"><%= image_tag current_user.avatar.url(:thumb) %>

<div class="span"><p><%= c.label "在此处输入您的评论:" %></p><p><%= c.text_area :comment_text %></p><p><%= c.submit提交评论",类别:btn btn-tiny"%></p>

<%结束%>

所以问题是当我在写CommentsController时,我不知道如何将照片的id(photo_id)从之前的show"页面传递给create方法.只有通过表单中的隐藏字段才能传递它吗?Rails 中有没有更优雅的方法来做到这一点?此外,关于安全的一点,如果我通过隐藏字段检索 photo_id,是否有人能够编写特定的发布"请求,以便它对相册中的所有照片发表评论?(就像很久以前 php 论坛中的垃圾邮件发送者..)

感谢您阅读本文并提前感谢您的回答!

解决方案

查看有关嵌套资源的 Rails 指南 http://guides.rubyonrails.org/routing.html#nested-resources

你的路线会有这样的东西.

资源:照片做资源:评论结尾

您的照片控制器将保持不变,但您的评论控制器需要从 url 中查找照片

class CommentsController <应用控制器before_action :get_photo定义创建@photo.comments.create(params.require(:comment).permit(:comment_text))....结尾...def get_photo@photo = Photo.find(params[:photo_id])结尾结尾

并且照片视图会有

<%= form_for [@photo,Comment.new], html: {method: :post} do |c|%><div class="row"><div class="span"><%= image_tag current_user.avatar.url(:thumb) %>

<div class="span"><p><%= c.label "在此处输入您的评论:" %></p><p><%= c.text_area :comment_text %></p><p><%= c.submit提交评论",类别:btn btn-tiny"%></p>

<%结束%>

应该调用 new_photo_comment_path

至于 user_id,我会从 user_signed_in 助手中获取它.既然你已经让他们登录了,那么从网上传递它是没有意义的.

I am trying to build a gallery with commenting function. Consider there are 3 classes: Album, Photo, Comment. The relation of these objects are Album has many Photos, Photo has many Comments.

Each Comment is left by registered user, thus in the comment object there are comment_text, user_id, and photo_id (Referring to the photo which the comment belongs).

I am trying to create a comment form under each photo's "show" view. Here is some of the Controller and the Show view:

controllers/photos_controller.rb

class PhotosController < ApplicationController
    ...
    def show
       @photo = Photo.find(params[:id])
       @new_comment = @photo.comments.build if user_signed_in?
       @comment_items = @photo.comments.paginate(page: params[:page])
    end 
    ...
end

views/photos/show.html.erb

...
<%= form_for @new_comment, html: {method: :post} do |c| %>
    <div class="row">
        <div class="span">
            <%= image_tag current_user.avatar.url(:thumb) %>
        </div>
        <div class="span">
            <p><%= c.label "Enter your comment here:" %></p>
            <p><%= c.text_area :comment_text %></p>
            <p><%= c.submit "Submit Comment", class: "btn btn-tiny" %></p>
        </div>
    </div>
<% end %>

So the problem is when I am writing the CommentsController, I do not know how to pass the photo's id (photo_id) from the previous "show" page to the create method. Is it only possible if a pass it thru via a hidden field in the form? Are there any more elegant way in Rails to do so? Besides, a point on security, if I retrieve the photo_id via a hidden field, will someone be able to write a specific "post" request so that it post comments to all photos in the album? (like spammer in the php's forum long time ago..)

Thank you for reading this and thanks in advance for answering!

解决方案

take a look at the rails guides on nested resources http://guides.rubyonrails.org/routing.html#nested-resources

your routes would have something like this.

resources :photos do
  resources :comments
end

your photo controller would stay the same, but your comments controller would need to lookup the photo from the url

class CommentsController < ApplicationController
    before_action :get_photo
    def create
       @photo.comments.create(params.require(:comment).permit(:comment_text))
       ....
    end 
    ...

    def get_photo
      @photo =  Photo.find(params[:photo_id])
    end
end

and the photo view would have

<%= form_for [@photo,Comment.new], html: {method: :post} do |c| %>
    <div class="row">
        <div class="span">
            <%= image_tag current_user.avatar.url(:thumb) %>
        </div>
        <div class="span">
            <p><%= c.label "Enter your comment here:" %></p>
            <p><%= c.text_area :comment_text %></p>
            <p><%= c.submit "Submit Comment", class: "btn btn-tiny" %></p>
        </div>
    </div>
<% end %>

which should invoke the new_photo_comment_path

as for the user_id i would just grabbed that from the user_signed_in helper. Since you already have them logged in, no sense in passing it in from the web.

这篇关于如何使用另一个对象的 id 调用对象的 create 方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆