2015-12-11 126 views
1

我在我的應用程序中設置了一個多態關聯。圖片屬於記分板模型和用戶模型,如圖所示。每個記分牌和用戶都有一張照片。我也有嵌套的路線,圖片資源嵌套在用戶和記分牌資源中。多態和has_one關聯

routes文件的用戶:

resources :users do 
    resources :picture 
end 

resources :account_activations, only: [:edit] 
resources :password_resets, only: [:new, :create, :edit, :update] 

resources :conversations, only: [:index, :show, :destroy] do 
    member do 
    post :reply 
    post :restore 
    post :mark_as_read 
    end 

    collection do 
    delete :empty_trash 
    end 
end 

路由文件記分牌:

resources :scoreboards do 
    member do 
    put :favourite 
    get :deleteteams 
    get :deleteschedules 
    end 

    resources :invitations, only: [:new, :create] 
    resources :comments 
    resources :teams, only: [:edit, :create, :destroy, :update] 
    resources :schedules 
    resources :picture 
end 

我已經建立了畫面控制器。代碼如下。

<div id= "uploadphoto"> 
    <%= form_for([@pictureable, @picture], url: scoreboard_picture_path, html: {multipart: true}) do |f| %> 
    <%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png', id: "files", class: "hidden" %> 
    <label for="files" id="picture"><h4 id="picturetext">Click Here to Upload Picture</h4></label> 
     <div class="modal" id="modal-1"> 
     <div class="modal-dialog"> 
      <div class="modal-content"> 
      <div class="modal-header">Position and Crop your Image</div> 
      <div class="modal-body"> 
       <div class="upload-preview"> 
       <img id="image" /></img> 
       </div> 
       <%= f.submit "upload photo" %> 
      </div> 
      <div class="modal-footer"> Click Anywhere Outside the box to Cancel</div> 
     </div> 
     </div> 
    </div> 
    <% end %> 
</div> 

我遇到的問題是與URL:下面

class PictureController < ApplicationController 
    before_filter :load_pictureable 

    def new 
    @picture = @pictureable.build_picture        
    end            

    def create 
    end 

    def destroy 
    end 

    private 

    def picture_params 
    params.require(:picture).permit(:picture) 
    end 

    def load_pictureable 
    klass = [User, Scoreboard].detect { |c| params["#{c.name.underscore}_id"] } 
    @pictureable = klass.find(params["#{klass.name.underscore}_id"]) 
    end 
end       

我的新的形式給出。這給了我以下錯誤。

No route matches {:action=>"show", :controller=>"picture", :scoreboard_id=>"13"} missing required keys: [:id] 

我不知道爲什麼它重定向我的表演動作,我認爲它可能是嵌套routes.I不知道是什麼問題。我以爲我通過傳遞以下網址new_scoreboard_picture_path來解決它。但是,當我按上傳照片時,它會讓我回到相同的URL。這是有道理的,因爲我明確指出了新形式的URL。但是,這是不正確的。如果有人能幫我弄清楚問題是什麼,這將是一個很大的幫助。我只包括相關的代碼。但是,如果我缺少任何東西,請讓我知道。任何解釋爲什麼我得到這個錯誤也會澄清我的過程。這是第一次使用多態關聯。任何形式的幫助將是偉大的!

+0

請遵循軌控制器從[這裏]命名約定(http://guides.rubyonrails.org/action_controller_overview.html#controller-naming-convention)。你能否從瀏覽器粘貼呈現的HTML代碼? –

+0

如果您還可以顯示'routes.rb'代碼 –

+0

@ Jay-ArPolidario,我將編輯我的原始問題幷包含記分牌和用戶的所有相關路線文件。 – kpaul

回答

0

我會用繼承和兩個獨立的控制器,而不是:

# the base controller 
class PicturesController < ApplicationController 
    before_action :load_pictureable 

    def new 
    @picture = @pictureable.build_picture        
    end            

    def create 
    @picture = @pictureable.build_picture 
    if @picture.save 
     do_redirect 
    else 
     render_errors 
    end 
    end 

    def destroy 
    # ... 
    end 

    private 

    def picture_params 
    params.require(:picture).permit(:picture) 
    end 

    # Finds the picturable based on the module name of the class 
    # for examples `Pets::PicturesController` will look for 
    # Pet.find(params[:pet_id]) 
    def find_pictureable 
    # this looks at the class name and extracts the module name 
    model_name = self.class.deconstantize.singularize 
    @pictureable = model_name.constanize.find(params["#{model_name}_id"]) 
    end 

    # subclasses can override this to whatever they want 
    def do_redirect 
    redirect_to @pictureable 
    end 

    # subclasses can override this to whatever they want 
    def render_errors 
    render :new 
    end 
end 

然後設置路線:

resources :users do 
    resource :picture, controller: 'users/pictures' 
end 

resources :scoreboards do 
    resource :picture, controller: 'scoreboards/pictures' 
end 

由於用戶/記分牌可以有我們使用resource,而不是resources只有一張圖片。這爲單數資源設置了路線。使用rake routes來查看自己的差異。例如,您使用POST /users/:user_id/picture創建一張圖片。

然後,我們建立孩子的控制器:

# app/controllers/users/pictures_controller.rb 
class Users::PicturesController < PicturesController 
end 

# app/controllers/scoreboards/pictures_controller.rb 
class Scoreboards::PicturesController < PicturesController 
end 

這使得無if/elseswitch語句混亂定製程度高的。此外,這防止惡意用戶通過params[:user_id]操縱用戶圖片。您絕不應使用用戶輸入來確定類或數據庫表。

而且你不需要明確指定表格網址:

<%= form_for([@pictureable, @picture], html: {multipart: true}) do |f| %> 

將使用users_picture_path(user_id: @pictureable.id)或相同的記分牌。

+0

爲了簡潔起見,我沒有添加它,但是您應該考慮清除步驟,即刪除孤立的圖片記錄。 – max