【问题标题】:Rails - Use nested form to create new recordsRails - 使用嵌套表单创建新记录
【发布时间】:2015-11-23 09:57:23
【问题描述】:

我有一个用于用户、投资组合和照片的嵌套表单。基本上,用户可以通过以另一种形式上传照片来创建投资组合。但是,然后我想给他们一个创建新作品集的机会,方法是从他们正在查看的当前作品集中选择一些照片,并让 PortfolioController 中的方法 resubmit 为他们创建一个新作品集。这些模型是:

class User < ActiveRecord::Base
    has_many: portfolios
end

class Portfolio < ActiveRecord::Base
    has_many: photos
    belongs_to: user
end


class Photo < ActiveRecord::Base
    belongs_to: portfolio

    attr_accessor :move
end

控制器是:

class PortfolioController < ApplicationController
    //... some generic code

    def resubmit
        // This is where I need help
    end

    def display
        @userPortfolio = Portfolio.where(:id => params[:uid]).first
    end
end

视图是:

<%= simple_form_for @userPortfolio, :url => {:action => resubmit} do |f|%>
    <%= f.label current_user.name %>
    <% @images = @userPortfolio.photos %>
    <% @images.each do |anImage| %>
        <%= f.fields_for :anImage do |ff| %>
            <%= ff.checkbox :move, :id => "move_#{anImage.id}" %><%=ff.label :move, "Move image #{anImage.name} to new portfolio?" %>

        <% end %>
    <% end %>

    <%= f.submit "Create new portfolio" %>
<% end %>

基本上,一旦用户点击提交,我希望 resubmit 方法创建一个新的投资组合,其中包含与所选照片相同的新照片集合。也就是说,我想创建1条新记录portfolio和几条新记录photo,根据用户选择的照片的属性,用户选择的数量,所以我需要访问代表的记录选择的照片。如何访问用户选择的所有照片?我不能简单地在表单上创建一组有限的复选框控制器,因为显示的数量取决于当前投资组合中的照片数量。

【问题讨论】:

    标签: ruby-on-rails forms


    【解决方案1】:

    使用 gemnested_form 或 cocoon 使元素动态化。在后端使用选定的项目为新的投资组合创建条目。

    【讨论】:

    【解决方案2】:

    好吧,看来我要做的事情毕竟相当简单。不需要nested_form,simple_form 也一样。但我确信 nested_form (正如 Tory SK 建议的那样)也能做到这一点。重点是在代码中添加attr_accessor:

    基本上代码如下:

    class User < ActiveRecord::Base
        has_many: portfolios
    end
    
    class Portfolio < ActiveRecord::Base
        has_many: photos
        belongs_to: user
    
        attr_accessor: photos_attributes // This is an important piece of code
    end
    
    
    class Photo < ActiveRecord::Base
        belongs_to: portfolio
    
        attr_accessor :move
    end
    

    然后我简单地将表格更改如下(注意额外的:pid =&gt; params[:pid],以便我可以在resubmit 中找出如果我需要访问它需要访问哪个投资组合):

    <%= simple_form_for @userPortfolio, :url => {:action => "resubmit", :pid => params[:pid]} do |f|%>
        <%= f.label current_user.name %>
        <% @images = @userPortfolio.photos 
           i = 0
        %>
        <%= f.fields_for :images do |ff| %>
                <% anImage = @images[i] %>
                <%= ff.checkbox :move, :id => "move_#{anImage.id}" %><%=ff.label :move, "Move image #{anImage.name} to new portfolio?" %>
                <% i = i+1%>
        <% end %>
    
        <%= f.submit "Create new portfolio" %>
    <% end %>
    

    当您点击提交并将表单发送到 resubmit 时,params 字典包含以下内容:

    {"utf8"=>"✓",
     ... more parameters
     "portfolio"=>{"photos_attributes"=>{"0"=>{"move"=>"0",
                                               "id"=>"1"},
                                         "1"=>{"move"=>"0",
                                               "id"=>"2"},
                                         ...
    
                                         "4"=>{"move"=>"0",
                                               "id"=>"5"}}},
     "commit"=>"Submit Job",
     "pid"=>"1"}
    

    现在我可以遍历复选框并将它们与属于 resubmit 中当前投资组合的所有照片进行比较

    def resubmit
        @myImages = Portfolio.where(:id => params[:pid]).photos
        // iterate through each image and use a counter to access 
        // the dictionary elements to see if they were checked
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-17
      • 1970-01-01
      相关资源
      最近更新 更多