2014-07-03 91 views
0

我有兩個模型;收藏和圖像Rails拖放更改對象屬性

收集模型

class Collection < ActiveRecord::Base 
    has_many :images, dependent: :destroy 
    accepts_nested_attributes_for :images 
end 

圖像模型

class Image < ActiveRecord::Base 
    belongs_to :collection  
    mount_uploader :file, ImageUploader 
end 

一件收藏品的has_many:圖像

在顯示所有圖片在網格視圖縮略圖我edit_collection圖林。目前我沒有辦法將圖像發送到其他收藏。由於我不想強制用戶一次編輯圖像,因此我認爲這將是使用拖放功能更改圖像所屬集合的好機會。

林認爲,在我的edit_collection頁面,其中有圖像縮略圖的網格,我會有一個側面收藏列表。允許用戶將圖像縮略圖拖動到集合上以更改圖像的collection_id值。

由於我仍然很漂亮,我正在尋找一個教程,解決以這種方式改變一個屬性,或者一個寶石,或任何建議。到目前爲止,我發現的所有材料似乎都集中在使用拖放來更改列表的層次結構。

有沒有人有任何建議?

回答

0

您可能會想爲此使用ajax。

因此,當他們將圖片拖動到一個新的集合中時,在本地更新圖片以獲得新的id,並且發送一個ajax請求到一個新的控制器動作來處理這個。你會傳入舊的圖片ID和新的集合來更新所需的屬性。

由於你的標籤,我想你已經知道如何去這個,但是,例如:

在前端側,每當畫面被拖入一個新的集合,你可以做這樣的事情。

$.ajax({ 
    url: '/images/8', 
    type: 'PUT', 
    data: { new_collection: collection_id }, 
    success: function (response) { 
     //do whatever you need, like maybe assigning the new id to the picture you have locally. 
    }, 
    error: function (response) { 
     // do whatever you'd do if it failed, like maybe ask them to try again. Since user is just dragging, ideally this would never happen, but perhaps they don't have internet connection. Again, at this point it becomes a matter of saying they can't do that without internet connection or maybe caching it locally, telling them you've cached it and that you'd go forward and do that when they have internet in the future. Tougher, but cooler and maybe nice to learn. 
    } 
}); 

在鐵軌邊,在routes.rb你會碰到這樣的:

resources :images其中包括上面的路線。

然後,在控制器ImagesController中,您將擁有以下內容。

def update 
    @image = Image.find(params[:id]) 

    @image.assign_attributes(collection_id: params[:new_collection]) 

    if @image.save 
     render json: @image, status: 200 
    else 
     render json: @image.errors.full_messages #not sure if right off the top of my head. 
    end 
end 

基本上,這就是你要如何去做和做到這一點。

1

實現可拖動的功能需要某種類型的Javascript(我不知道任何可以抽象出來的寶石),所以請確保您首先熟悉Javascript/Ajax is used in Rails

從廣義上講,這種類型的應用最普遍的解決方案可能是jQuery draggabledroppable的組合。你可以通過使用jquery-ui-rails寶石(more instructions here)將它們加入到你的Rails應用程序中。你需要要求您app/assets/application.js文件需要的模塊:

//= require jquery 
... 
//= require jquery.ui.draggable 
//= require jquery.ui.droppable 
... 
//= require_tree . 

基本上你會希望你的控制器上需要一兩則params的(圖像idcollection_id要移動它會行動在這種情況下是一個好主意),找到該圖像並根據這些參數更改其集合,然後呈現Javascript或JSON響應以告知瀏覽器已做出更改(或不) - 這是假設您想保持這一頁。 e.g:

def change_collection 
    @image = Image.find(params[:id]) 
    @image.collection_id = params[:collection_id] 
    if @image.save 
    render json: ..., status: ... 
    else 
    render json: ..., status: ... 
    end 
end 

這僅僅是一個例子給你的想法,你可能不想分配PARAM一樣,直接說,由於安全方面的原因。

你需要指向該行動路線,e.g:

resources :images do 
    patch 'change_collection', on: :member 
end 

然後,你需要實現的事情JavaScript端。閱讀API documentation可拖動和拖放,以查看可用的方法/事件,並根據自己的喜好進行調整。你可能會做這樣的事情:

$(".html_class_representing_your_images").draggable(); 

$(".html_class_representing_your_collections").droppable({ 
    drop: function() { 
    Ajax request to the route we just made goes here 
    } 
}); 

你可以找到大量的信息如何使使用jQuery別處一個Ajax請求(包括如何使用成功/失敗處理程序),但我只是讓您知道您需要找到一種方法從您的DOM元素中獲取ids,傳統方法是在您的視圖中提供data屬性(在頂部鏈接的指南中提到)。在未來,如果您添加更多像這樣的花哨功能,並且您的應用程序開始在前端變得足夠複雜以至於無法保持您的Javascript組織,那麼您可能需要考慮像Backbone.js這樣的前端框架,而不是比如何依賴DOM。

無論如何,我希望這足以讓你至少開始。