Вызов метода обновления полиморфного контроллера напрямую

0

Я пытаюсь сделать ajax-обновление полиморфной модели и получить ошибку:

undefined method 'images' for #<Image:0x007fc6517ea378>
app/controllers/images_controller.rb, line 22 

(Он жалуется на @imageable.images этой строки @image = @imageable.images.find(params[:id]))

Эта модель/контроллер отлично функционирует, когда CRUDing экземпляры ее из других моделей, но, похоже, получает эту ошибку при попытке обновить ее напрямую.

Почему работает при использовании во вложенной форме, но не при обращении напрямую?

image.rb

class Image < ActiveRecord::Base
  default_scope order('images.id ASC')

  attr_accessible               :asset,
                                :asset_cache, 
                                :active

  belongs_to                    :imageable, polymorphic: true

  mount_uploader                :asset, ImageUploader

  def self.default
    return ImageUploader.new
  end
end

images_controller.rb

class ImagesController < ApplicationController
  before_filter :load_imageable
  load_and_authorize_resource

  def new
    @image = @imageable.images.new
  end

  def create
    @image = @imageable.images.new(params[:image])

    respond_to do |format|
      if @image.save
        format.html { redirect_to @imageable, notice: "Image created." }
      else 
        format.html { render :new }
      end
    end
  end

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

    respond_to do |format|
      if @image.update_attributes(params[:image])
        format.html { redirect_to @imageable, notice: 'Image was successfully updated.' }
      else
        format.html { render :edit }
      end
    end
  end

  def destroy
    @image = @imageable.images.find(params[:id])
    @image.destroy
  end


  private

  def load_imageable
    resource, id = request.path.split('/')[1, 2]
    @imageable = resource.singularize.classify.constantize.find(id)
  end
end

ajax call

$(document).on("click", ".toggle-image-active", function(event) {
  var id = $(this).attr("data-id");
  var currently_active = $(this).attr("data-active");
  var active = true;

  if (currently_active == "true") {
    active = false;
  }

  $.ajax({
    type: "PUT",
    dataType: "script",
    url: '/images/' + id,
    contentType: 'application/json',
    data: JSON.stringify({ resource:{active:active}, _method:'put' })
  }).done(function(msg) {
    console.log( "Data Saved: " + msg );
  });
});
Теги:
polymorphism

1 ответ

0
Лучший ответ

То, что я не понимал, и причина, по которой это не работает, заключается в том, что @imageable на самом деле является моделью, к которой принадлежит модель image, а не сама модель image.

В качестве решения я определил действие пользовательского контроллера и сделал для него сообщение.

class ImagesController < ApplicationController
  before_filter :load_imageable
  skip_before_filter :load_imageable, :only => :set_active
  load_and_authorize_resource

  def set_active
    Image.find(params[:id]).update_attributes(params[:image])
    render :nothing => true, :status => 200, :content_type => 'text/html'
  end

Хотя это работает, это может быть не лучшее решение, поэтому я открыт для предложений.

  • 0
    Я также должен был определить собственный маршрутный post '/images/set_active/:id' => 'images#set_active'

Ещё вопросы

Сообщество Overcoder
Наверх
Меню