彼
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