0

几个小时试图研究一个解决方案,发现一些非常类似的问题like this onethis one,虽然所有建议的修补程序不' t解决我的问题:嵌套窗体内嵌套窗体 - 茧宝石:3级孩子不保存 - Rails 5

尝试使用Cocoon Gem在嵌套窗体内部构建一个嵌套窗体,尽管第三级子窗体不保存到数据库。

的车型很简单的结构,只有 “的has_many/belongs_to的” 关系:

文本有很多的报价。报价有很多评论。

在实现中的动态UI交互工作,添加和删除字段的工作,但不幸的是,只有文本和引号被保存,而不是注释。没有显示错误。

这里是形式:

_text_form.html.erb

<%= form_for(@text, html: { multipart: true }) do |f| %> 
    <%= render 'shared/error_messages', object: f.object %> 
    <div class="field"> 
    <%= f.text_field :title, placeholder: "Enter Title" %>  
    </div> 
    <div> 
     <h3>Quotes:</h3> 
     <div id="quotes"> 
     <%= f.fields_for :quotes do |quote| %> 
      <%= render 'quote_fields', f: quote %> 
     <% end %> 

     <div class="links"> 
      <%= link_to_add_association 'add quote', f, :quotes, class: "btn btn-default" %> 
     </div> 
     </div> 
    </div> 

    <%= f.submit %> 
<% end %> 

_quote_fields.html.erb

<div class="nested-fields"> 
    <%= f.text_area :content, placeholder: "Compose new quote..." %> 
    <span class="picture"> 
    <%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %> 
    </span> 

    <div> 
     <h3>Comments:</h3> 
     <div id="comments"> 
     <%= f.fields_for :comments do |comment| %> 
      <%= render 'comment_fields', f: comment %> 
     <% end %> 
     <div class="links"> 
      <%= link_to_add_association 'add comment', f, :comments, class: "btn btn-default" %> 
     </div> 
     </div> 
    </div> 
    <div class="links"> 
    <%= link_to_remove_association "remove quote", f, class: "btn btn-default" %> 
    </div> 
</div> 

<script type="text/javascript"> 
    $('#quote_picture').bind('change', function() { 
    var size_in_megabytes = this.files[0].size/1024/1024; 
    if (size_in_megabytes > 2) { 
     alert('Maximum file size is 2MB. Please choose a smaller file.'); 
    } 
    }); 
</script> 

_comment_fields.html.erb

<div class="nested-fields"> 
    <%= f.text_area :bodycomment, placeholder: "Write a comment..." %> 
    <%= link_to_remove_association "remove comment", f, class: "btn btn-default" %> 
</div> 

下面是型号:

text.rb

class Text < ApplicationRecord 
    belongs_to :user, inverse_of: :texts 
    has_many :quotes, dependent: :destroy, inverse_of: :text 
    has_many :comments, :through => :quotes 
    accepts_nested_attributes_for :quotes, reject_if: :all_blank, allow_destroy: true 
    accepts_nested_attributes_for :comments, reject_if: :all_blank, allow_destroy: true 
    default_scope -> { order(created_at: :desc) } 
    mount_uploader :coverimage, CoverimageUploader 

    validates :user_id, presence: true 
    validates :title, presence: true 
    validate :coverimage_size 

    private 

     # Validates the size of an uploaded picture. 
     def coverimage_size 
     if coverimage.size > 5.megabytes 
      errors.add(:coverimage, "should be less than 5MB") 
     end 
     end 

end 

quote.rb

class Quote < ApplicationRecord 
    belongs_to :text, inverse_of: :quotes 
    has_many :comments, dependent: :destroy, inverse_of: :quote 
    accepts_nested_attributes_for :comments, reject_if: :all_blank, allow_destroy: true 

    mount_uploader :picture, PictureUploader 
    validates :content, presence: true, length: { maximum: 350 } 
    validate :picture_size 

private 

    #Validates size of image upload 
    def picture_size 
    if picture.size > 2.megabytes 
     errors.add(:picture, "should be less than 2MB") 
    end 
    end 

end 

comment.rb

class Comment < ApplicationRecord 
    belongs_to :quote, inverse_of: :comments 
    validates :quote_id, presence: true 
    validates :bodycomment, presence: true 

end 

这里控制器:

quotes_controller.rb

class QuotesController < ApplicationController 
before_action :logged_in_user, only: [:create, :destroy] 
before_action :correct_user, only: :destroy 


    def show 
    end 



    def create 
    @quote = current_user.quotes.build(quote_params) 
    if @quote.save 
    flash[:success] = "Quote created!" 
    redirect_to root_url 
    else 
    @feed_items = [] 
    render 'static_pages/home' 
    end 
    end 

    def destroy 
    @quote.destroy 
    flash[:success] = "Quote deleted" 
    redirect_to request.referrer || root_url 
    end 


    private 

    def quote_params 
     params.require(:quote).permit(:content, :picture, comments_attributes: [:id, :bodycomment 
     , :_destroy]) 
    end 

    def correct_user 
     @quote = current_user.quotes.find_by(id: params[:id]) 
     redirect_to root_url if @quote.nil? 

    end 

end 

comments_controller.rb

class CommentsController < ApplicationController 
before_action :logged_in_user, only: [:create, :edit, :update, :destroy] 
before_action :correct_user, only: :destroy 


    def show 
    end 

    def create 
     @comment = current_user.comments.build(comment_params) 
     if @comment.save 
      flash[:success] = "Comment created!" 
      redirect_to root_url 
     else 
      @feed_items = [] 
      render 'static_pages/home' 
     end 
     end 

    def destroy 
     @comment.destroy 
     flash[:success] = "Comment deleted" 
     redirect_to request.referrer || root_url 
    end 

    private 

    def comment_params 
      params.require(:comment).permit(:bodycomment) 
    end 

    def correct_user 
     @comment = current_user.comments.find_by(id: params[:id]) 
     redirect_to root_url if @comment.nil? 

    end 

end 

想知道是否有一些JavaScript的问题...

非常感谢您的关注。非常感谢,并感谢您的帮助。

编辑

这里是texts_controller。RB

class TextsController < ApplicationController 
    before_action :logged_in_user, only: [:create, :edit, :update, :destroy] 
    before_action :correct_user, only: :destroy 
    before_action :find_text, only: [:show, :edit, :update, :destroy] 


    def show 
    end 

    def new 
    @text = current_user.texts.build 
    end 

    def create 
    @text = current_user.texts.build(text_params) 
    if @text.save 
    flash[:success] = "Text created!" 
    render 'show' 
    else 
    render 'static_pages/home' 
    end 
    end 


    def edit 
    end 

    def update 
    if @text.update(text_params) 
     redirect_to root_url 
    else 
     render 'edit' 
    end 
    end 

    def destroy 
    @text.destroy 
    flash[:success] = "Text deleted" 
    redirect_to request.referrer || root_url 
    end 

    private 

    def text_params 
    params.require(:text).permit(:url, :title, :coverimage, 
            :publication, :author, :summary, quotes_attributes: [:id, :content, :picture, :_destroy], comments_attributes: [:id, :bodycomment, :_destroy]) 
    end 

    def find_text 
     @text = Text.find(params[:id]) 
     end 

    def correct_user 
     @user = User.find(params[:id]) 
     redirect_to(root_url) unless current_user?(@user) 
    end 

end 

这里有一些日志的相关信息,我保存的表单字段后得到:

--- !ruby/object:ActionController::Parameters 
parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess 
    utf8: "✓" 
    authenticity_token: NQLh7TwlhfbV4ez91HGMyYZK6YYYiLXhHG/cAhrAsRylIAuFFhjnKX0vEO8ZIVbsxGES3byBgUMz21aSOlGiqw== 
    text: !ruby/object:ActionController::Parameters 
    parameters: !ruby/hash:ActiveSupport::HashWithIndifferentAccess 
     title: Title of the Book 
     quotes_attributes: !ruby/hash:ActiveSupport::HashWithIndifferentAccess 
     '1490626822148': !ruby/hash:ActiveSupport::HashWithIndifferentAccess 
      content: This is a quote from the book. 
      _destroy: 'false' 
      comments_attributes: !ruby/hash:ActiveSupport::HashWithIndifferentAccess 
      '1490626833771': !ruby/hash:ActiveSupport::HashWithIndifferentAccess 
       bodycomment: Here is a comment on the quote of the book. 
       _destroy: 'false' 
    permitted: false 
    commit: Create Text 
    controller: texts 
    action: create 
permitted: false 

这里的日志文件形成终端:

Started POST "/texts" for ::1 at 2017-03-27 17:00:51 +0200 
Processing by TextsController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"NQLh7TwlhfbV4ez91HGMyYZK6YYYiLXhHG/cAhrAsRylIAuFFhjnKX0vEO8ZIVbsxGES3byBgUMz21aSOlGiqw==", "text"=>{"title"=>"Title of the Book", "publication"=>"", "author"=>"", "url"=>"", "summary"=>"", "quotes_attributes"=>{"1490626822148"=>{"content"=>"This is a quote from the book.", "_destroy"=>"false", "comments_attributes"=>{"1490626833771"=>{"bodycomment"=>"Here is a comment on the quote of the book.", "_destroy"=>"false"}}}}}, "commit"=>"Create Text"} 
    User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] 
Unpermitted parameter: comments_attributes 
    (0.1ms) begin transaction 
    SQL (0.7ms) INSERT INTO "texts" ("user_id", "url", "title", "publication", "author", "summary", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?) [["user_id", 1], ["url", ""], ["title", "Title of the Book"], ["created_at", 2017-03-27 15:00:51 UTC], ["updated_at", 2017-03-27 15:00:51 UTC]] 
    SQL (0.4ms) INSERT INTO "quotes" ("content", "created_at", "updated_at", "text_id") VALUES (?, ?, ?, ?) [["content", "This is a quote from the book."], ["created_at", 2017-03-27 15:00:51 UTC], ["updated_at", 2017-03-27 15:00:51 UTC], ["text_id", 366]] 
    (1.3ms) commit transaction 
    Rendering texts/show.html.erb within layouts/application 
    Quote Load (0.2ms) SELECT "quotes".* FROM "quotes" WHERE "quotes"."text_id" = ? [["text_id", 366]] 
    Rendered texts/show.html.erb within layouts/application (5.8ms) 
    Rendered layouts/_shim.html.erb (0.5ms) 
    Rendered layouts/_header.html.erb (1.4ms) 
    Rendered layouts/_footer.html.erb (1.8ms) 
Completed 200 OK in 127ms (Views: 100.1ms | ActiveRecord: 3.1ms) 
+1

你能告诉什么是发布到控制器? (你可以在日志文件中找到它)并且你能够显示来自'TextsController'的强大参数定义(注释和引用控制器与嵌套表单无关 - 整个表单发布到textscontroler) – nathanvda

+0

... didn看到@nathanvda(宝石的制造者)在我发布之前一直在这里!哎呀! – Mirv

+0

@nathanvda真的很感激你正在研究这个!非常感谢。我添加了texts_controller.rb以及上面的一些日志文件。 – YvonC

回答

2
  1. 模型.. text.rb ...我不得不把accepts_nested_attributes_for :comments ...除了已经发布的
  2. TextController ...您的嵌套允许PARAMS需要在这里发生,.permit(:content, :picture, quotes_attributes: [:id, :content, :picture, :_destroy, comments_attributes: [:id, :bodycomment, :_destroy]])

我可能有变量名断位(尤其是你没有列出的TextController),但基本上,它看起来像你的正试图通过其他控制器继承嵌套 - 当唯一被调用的控制器是TextController时。

可以肯定的是,在第二个控制台中放置一个tail -f log/<logname>,或者在执行保存/更新以查看许可问题时查看终端控制台。

让我知道是否仍然存在问题!根据新的控制器

...更新

控制器需要调整(你有一个放错地方的“]”现在)。

params.require(:text).permit(:url, :title, :coverimage, 
            :publication, :author, :summary, quotes_attributes: [:id, :content, :picture, :_destroy, comments_attributes: [:id, :bodycomment, :_destroy]]) 

,直到你解决这个模型也将无法工作......

accepts_nested_attributes_for :comments 
+0

感谢您的帮助,并遗憾地忘记添加TextController ...以为我会发布它。它现在在那里。我尝试在text.rb中添加“accep_nested_attributes_for”以用于评论...但是没有成功。看到上面的日志。 – YvonC

+2

好吧,所以问题看起来像2个部分 - 你需要添加accept_for返回&当你看看你的控制器允许的值为TextController ...你没有在'quotes'里面的'comments',他们在那里属于......仔细阅读我的答案,在#2的最后有两个右括号(一个用于引号和一个用于注释)彼此相邻。 – Mirv

+0

Imho的'accepted_nested_attributes'已经可以,但是确实强的参数必须嵌套,如发送给控制器(并记录在日志文件中)所指示的那样。 – nathanvda