1

Rails アプリケーション (Post、Picture) には、次のように関連付けられた 2 つのモデルがあります。

#Post model
has_many :pictures, :dependent => :destroy 
accepts_nested_attributes_for :pictures, :allow_destroy => true 

#Picture model
belongs_to :post

投稿編集ビューには 2 つのフォームがあるため、投稿のコンテンツを編集したり、投稿に写真を追加したりできます。jquery ファイル アップロード プラグインを Carrierwave と一緒に使用して、アップロード プロセスを処理します。これは、 http://tinyurl.com/aun7bl5のこのセットアップと非常によく似ています。

ポスト編集ビューに移動すると、jquery ファイルのアップロードは常にすべての画像を表示します。これは、すべての画像を取得して json にレンダリングする画像コントローラーのインデックス アクションを使用して、jquery ファイルのアップロードで処理できるようにするためです。インデックス アクションは次のようになります。

def index
  @pictures = Picture.all 
  render :json => @pictures.collect { |p| p.to_jq_upload }.to_json
end

投稿パラメーター (:id) は、投稿を編集するときに投稿コントローラーで使用できます。ロガーで見れます。ただし、投稿編集フォーム内にネストされている index アクションでは使用できません。

ここで私の質問は、編集したい投稿のIDを投稿コントローラーのインデックスアクションに提供して、取得した画像をフィルタリングするために次のようなことを行う方法です。

def index
  @pictures = Picture.where(:post_id => params[:id])
  render :json => @pictures.collect { |p| p.to_jq_upload }.to_json
end

編集:

#Post#edit view
<div class=post-well>
  <div class="page-header">
    <h1>Reisebericht editieren</h2>
  </div>

  <%= simple_form_for @post do |f| %>
    <%= f.error_notification %>
    <div class="form-inputs">
      <%= f.input :title, :label => "Titel", :input_html => { :class => 'new-post-inputfields' } %>
      <%= f.input :body, :label => "Artikel", :input_html => { :class => 'new-post-inputfields' } %>
      <%= f.hidden_field :picture_ids, :input_html => { :id => 'post_picture_ids' } %> 
      <%= f.button :submit, :label => "Speichern" %>
    </div> 
  <% end %>

  <h4>Bilder verwalten</h4>
  <%= simple_form_for Picture.new, :html => { :multipart => true, :id => "fileupload"  } do |f| %>
    <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
    <div class="row fileupload-buttonbar">
      <div class="span7">
        <!-- The fileinput-button span is used to style the file input field as button -->
        <span class="btn btn-success fileinput-button">
          <i class="icon-plus icon-white"></i>
          <span>Hinzufügen</span>
          <%= f.file_field :path, multiple: true, name: "picture[path]" %>
        </span>
        <button type="submit" class="btn btn-primary start">
          <i class="icon-upload icon-white"></i>
          <span>Upload</span>
        </button>
        <button type="reset" class="btn btn-warning cancel">
          <i class="icon-ban-circle icon-white"></i>
          <span>Abbrechen</span>
        </button>
        <button type="button" class="btn btn-danger delete">
          <i class="icon-trash icon-white"></i>
          <span>Delete</span>
        </button>
        <input type="checkbox" class="toggle">
      </div>
      <div class="span5">
        <!-- The global progress bar -->
        <div class="progress progress-success progress-striped active fade">
          <div class="bar" style="width:0%;"></div>
        </div>
      </div>
    </div>
    <!-- The loading indicator is shown during image processing -->
    <div class="fileupload-loading"></div>
    <br>
    <!-- The table listing the files available for upload/download -->
    <table class="table table-striped"><tbody class="files" data-toggle="modal-gallery" data-target="#modal-gallery"></tbody>
    </table>
  <% end %>
</div> 

<script>
  var fileUploadErrors = {
    maxFileSize: 'File is too big',
    minFileSize: 'File is too small',
    acceptFileTypes: 'Filetype not allowed',
    maxNumberOfFiles: 'Max number of files exceeded',
    uploadedBytes: 'Uploaded bytes exceed file size',
    emptyResult: 'Empty file upload result'
  };
</script>

<!-- The template to display files available for upload -->
<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
  <tr class="template-upload fade">
    <td class="preview"><span class="fade"></span></td>
      <td class="name"><span>{%=file.name%}</span></td>
        <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
        {% if (file.error) { %}
          <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
        {% } else if (o.files.valid && !i) { %}
          <td>
            <div class="progress progress-success progress-striped active"><div class="bar" style="width:0%;"></div></div>
            </td>
            <td class="start">{% if (!o.options.autoUpload) { %}
              <button class="btn btn-primary">
                <i class="icon-upload icon-white"></i>
                  <span>{%=locale.fileupload.start%}</span>
                </button>
            {% } %}</td>
        {% } else { %}
          <td colspan="2"></td>
        {% } %}
        <td class="cancel">{% if (!i) { %}
          <button class="btn btn-warning">
            <i class="icon-ban-circle icon-white"></i>
              <span>{%=locale.fileupload.cancel%}</span>
            </button>
        {% } %}</td>
    </tr>
{% } %}
</script>
<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
  <tr class="template-download fade">
    {% if (file.error) { %}
      <td></td>
        <td class="name"><span>{%=file.name%}</span></td>
          <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
            <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
        {% } else { %}
          <td class="preview">{% if (file.thumbnail_url) { %}
            <a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a>
            {% } %}</td>
            <td class="name">
              <a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&'gallery'%}" download="{%=file.name%}">{%=file.name%}</a>
            </td>
            <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
            <td colspan="2"></td>
        {% } %}
        <td class="delete">
          <button class="btn btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">
            <i class="icon-trash icon-white"></i>
              <span>{%=locale.fileupload.destroy%}</span>
            </button>
            <input type="checkbox" name="delete" value="1">
        </td>
    </tr>
{% } %}
</script>

そしてJavaScript:

$(function () {  
  // Initialize the jQuery File Upload widget:
  $('#fileupload').fileupload({
  completed: function(e, data) {
     console.log(data.result[0].picture_id); 
     $("#post_picture_ids").val(function(i,val) { 
          return val + (val ? ', ' : '') + data.result[0].picture_id;
     });
   }
 });

 // Load existing files:
 $.getJSON($('#fileupload').prop('action'), function (files) {
  var fu = $('#fileupload').data('fileupload'), 
  template;
  fu._adjustMaxNumberOfFiles(-files.length);
  template = fu._renderDownload(files)
  .appendTo($('#fileupload .files'));
  // Force reflow:
  fu._reflow = fu._transition && template.length &&
  template[0].offsetWidth;
  template.addClass('in');
 $('#loading').remove();
 });
}); 

これについての助けをいただければ幸いです。

EDIT2:1つの解決策については、@SybariteManojの回答の下を参照してください。別の解決策は、次を使用することです。

$.getJSON($('#fileupload').prop('action') + '/' + $('#current_post_id').val(), function (files) {

get 関数の先頭で、次のように写真コントローラーのルートを追加します。

get 'pictures/:id', to: 'pictures#index'

pictures コントローラーの index アクションは、このソリューションの id パラメーターをフィルター処理し、次のようになります。

def index
  @pictures = Picture.where(:post_id => params[:id])
  render :json => @pictures.collect { |p| p.to_jq_upload }.to_json
end 

私は@SybariteManojの完全なソリューションを好むと思うので、ルートは必要なく、インデックスアクションは今このように機能します。

def index
  @pictures = Picture.where(:post_id => params[:post_id])
  render :json => @pictures.collect { |p| p.to_jq_upload }.to_json
end 
4

3 に答える 3

1

私は犯人を得たと思います。JavaScript では、$.getJSON($('#fileupload').prop('action')これは画像アップロード フォームの action 属性の値を渡しています。

この行を編集ビューファイルのどこかに追加してみてください

<%= hidden_field_tag :current_post_id, @post.id, :id => 'current_post_id' %>

この行を置き換えます

$.getJSON($('#fileupload').prop('action'), function (files) {

$.getJSON($('#fileupload').prop('action') + '?post_id=' + $('#current_post_id').val(), function (files) {

私はそれをテストしていませんが、これで問題が解決すると確信しています。

于 2013-02-01T14:58:07.007 に答える
1

投稿を編集しているため、投稿params[:id]は投稿コントローラーのupdateアクションで使用できますが、レールでフォームを編集した後のデフォルトのアクション呼び出しである他のユーザーでは使用できません。

アクションに必要な場合はparams[:id]index更新アクションが呼び出された後にインデックス アクションにリダイレクトするか、選択した画像を更新アクションにのみ表示するロジックを配置する必要があります。

投稿に属する写真を表示するプロセスを処理するカスタム アクション メソッドを作成することもできます。

于 2013-02-01T10:39:41.170 に答える