使用Ckeditor,Paperclip和Ruby on Rails无法为图片模型添加参数

时间:2013-04-14 18:39:00

标签: ruby-on-rails ruby ruby-on-rails-3 gem ckeditor

我有一个像这样的CKeditor图片模型:

class Ckeditor::Picture < Ckeditor::Asset
  before_save :set_vars
  has_attached_file :data,
                :url  => "/ckeditor_assets/pictures/:id/:style_:basename.:extension",
                :path => ":rails_root/public/ckeditor_assets/pictures/:id/:style_:basename.:extension",
                :styles => { :content => '600>',:medium => '300x300', :quintet => '150x150', :thumb => '118x100#' }

  validates_attachment_size :data, :less_than => 2.megabytes
  validates_attachment_presence :data

  def url_content
    url(:content)
  end

  protected
  def set_vars
    #self.assetable_id = id
    #self.assetable_type = controller_name
  end
end

我想要的是在创建新图片期间填充'assetable_id'和'assetable_type'(因为数据库表中有列的列)。我想传递它们的变量。就像图片链接到的帖子/事件/用户的id一样。当然,图片被分配给“模型”的类型 - 再次发布/事件/用户。

我不知道这是否是正确的解决方案,但我不知道如何解决它。关于CKeditor gem,配置设置和Rails的在线文档非常糟糕 - 我正在寻找几个小时和几个小时,我找不到一个与我想要的非常相似的东西 - 所以请帮忙。

我知道如何调整上传的参数,但它们似乎都没有做我想要的事情:

Started POST "/ckeditor/pictures?CKEditor=post%5B14%5D&CKEditorFuncNum=1&
langCode=en&%3Aassetable-id=0&assetable_type=post&
authenticity_token=fsKA68sxkzQpiSMmtcP782i4oI%2FA6KSIsSZuwO5zDWA%3D" for 127.0.0.1 at 
2013-04-15 10:05:06 +0200

Processing by Ckeditor::PicturesController#create as HTML

Parameters: {"upload"=>#<ActionDispatch::Http::UploadedFile:0x007f94f80beef8 
@original_filename="kb_new.png", @content_type="image/png", @headers="Content-
Disposition: form-data; name=\"upload\"; filename=\"kb_new.png\"\r\nContent-Type: 
image/png\r\n", @tempfile=#<File:/tmp/RackMultipart20130415-3130-1ls814r>>, 
"CKEditor"=>"post[14]", "CKEditorFuncNum"=>"1", "langCode"=>"en", ":assetable-id"=>"0", 
"assetable_type"=>"post", 
"authenticity_token"=>"fsKA68sxkzQpiSMmtcP782i4oI/A6KSIsSZuwO5zDWA="}
User Load (0.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
[ALL THE FORMATING STUFF]


SQL (0.6ms)  INSERT INTO `ckeditor_assets` (`assetable_id`, `assetable_type`, `created_at`, `data_content_type`, `data_file_name`, `data_file_size`, `height`, `type`, `updated_at`, `width`) VALUES (NULL, '0', '2013-04-15 08:05:07', 'image/png', 'kb_new.png', 291770, 419, 'Ckeditor::Picture', '2013-04-15 08:05:07', 450)

[paperclip] Saving attachments.

(62.5ms)  COMMIT

Rendered text template (0.0ms)

Completed 200 OK in 929ms (Views: 0.5ms | ActiveRecord: 63.6ms)

另请查看此问题:

How to set the size of an image within CKeditor in Ruby On Rails according to the picture model?

4 个答案:

答案 0 :(得分:5)

我实际上想出了这个并且有一个有效的解决方案。我也尝试使用Google搜索所有内容并找到关于如何在Rails中向Ckeditor上传添加自定义参数的ZERO信息。

这就是我的所作所为:

  1. 让我们从表单本身开始。使用Ckeditor,一切都由URL驱动。因此,当您单击图像图标,然后出现弹出窗口,然后单击BROWSE SERVER按钮时,您会注意到它会打开一个带有URL的新弹出窗口。这是您需要修改的第一个URL。然后,当您实际上传图像时,它会将发布请求发送到另一个URL。这是您需要修改的第二个URL。
  2. 默认情况下,这些URL设置为Ckeditor :: PicturesController上的“index”和“create”操作。这是gem's repo中此控制器文件的链接,稍后您将需要它 - https://github.com/galetahub/ckeditor/blob/2dd963fae117726976e5bf1dc264e27d3741fea8/app/controllers/ckeditor/pictures_controller.rb

    从逻辑上讲,我们需要做的是修改这些URL,以便我们可以添加自己的自定义代码来控制发生的事情。所以这就是我做的事情(请注意“ckeditor”哈希):

    <%= cktext_area_tag 'column1_body', @section, 
        :ckeditor => { 
          filebrowserImageUploadUrl: "/ckeditor/pictures?website_id=#{@website.id}",
          filebrowserImageBrowseUrl: "/picture_overrides" 
    } %>
    

    冷却。

    2.首先,我用'/ picture_overrides'修改了filebrowserImageBrowseUrl。这意味着当有人单击BROWSE SERVER按钮时,它将在我的PictureOverridesController上调用'index'动作。所以我添加了路由,创建了控制器文件和视图。

    对于视图,我完全从gem中复制了视图文件,这里是https://github.com/galetahub/ckeditor/blob/master/app/views/ckeditor/pictures/index.html.erb。注意:那里有一个部分,所以你也需要抓住它。

    现在在我的新'PictureOverridesController'文件中,我按如下方式编辑了'index'操作:

    def index
      # I need to find the website
      @website = Website.find_by_subdomain(request.subdomain)
      # I can scope @pictures to only contain the images the user should see.
      @pictures = Ckeditor::Picture.where(website_id: @website.id)
    end
    

    然后,在此过程中会调用其他一些私有方法,因此您还需要将以下代码添加到此控制器文件中(只需剪切和粘贴)。您会注意到我从ge​​m文件中的同一个控制器中获取了此代码。

      protected
    
      def find_asset
        @picture = Ckeditor.picture_adapter.get!(params[:id])
      end
    
      def authorize_resource
        model = (@picture || Ckeditor.picture_model)
        @authorization_adapter.try(:authorize, params[:action], model)
      end
    

    有了这个,现在我的用户只能看到具有正确website_id的图像。

    现在,我需要确保在用户通过Ckeditor上传图像时设置了website_id。

    3.虽然您当然可以修改此控制器文件上的创建操作,并将URL设置为此,但我选择了另一种方式。我只是将website_id添加到URL,如上所示。不幸的是,Ckeditor :: Picture实例不会自动保存。所以我决定用ApplicationController中的after_filter完成这个,就像这样:

        after_filter :ckeditor_add_website_id
    
        def ckeditor_add_website_id
          if params[:controller] == 'ckeditor/pictures' && params[:action] == 'create'
            @website = find_website_by_domain_subdomain(request)
            @picture.update_attributes(website_id: @website.id)
          end
        end
    

    它只是有效。

    最后 - 不要忘记将自定义网址添加到您使用Ckeditor的任何表单。

答案 1 :(得分:2)

在我看来最简单的解决方案:

#controllers/application_controller.rb
protected

def ckeditor_pictures_scope(options = { :assetable_id => "#{current_page.id}" ,:assetable_type => "Page" })
  ckeditor_filebrowser_scope(options)
end

def ckeditor_attachment_files_scope(options = { :assetable_id => "#{current_page.id}" ,:assetable_type => "Page" })
  ckeditor_filebrowser_scope(options)
end


def ckeditor_before_create_asset(asset)
  asset.assetable = current_page if current_page
  return true
end

答案 2 :(得分:1)

感谢nfriend21和wacaw提供他们的解决方案。 这个问题困扰了我一个星期!

wacaw的解决方案是最简单和最干净的,但我受到nfriend21的启发才能完成它。对于像我这样没有经验的人来说,它会很有用。

我有一个包含许多编辑器的页面,每个编辑器都有不同的ID(名为column_id)。 我希望column_id保存为Column类型的asset_id(在我的应用程序中定义的对象)。

1)我更改了页面中所有编辑器的网址:

for (instance in CKEDITOR.instances) {
          var editor = CKEDITOR.instances[instance];
          var id = editor.name.substr(6);

          if(editor) {
            editor.config.filebrowserImageBrowseUrl = "/ckeditor/pictures?column_id=" + id;
            editor.config.filebrowserImageUploadUrl = "/ckeditor/pictures?column_id=" + id;
          }
}

请注意,我将编辑器的id提取为包含它的div的ID的子字符串...即editor134,editor245等:我删除前6个字符。

另请注意,我使用了ckeditor gem的原始PicturesController。

2)现在,在ApplicationController中修改一下wacav解决方案:

#controllers/application_controller.rb
protected

  def ckeditor_pictures_scope(options = { :assetable_id => params[:column_id], :assetable_type => "Column"})
    ckeditor_filebrowser_scope(options)
  end

  # to be modified: at this moment I'm interested in pictures only
  def ckeditor_attachment_files_scope(options = { :assetable_id => "#{current_page.id}" ,:assetable_type => "Page" })
    ckeditor_filebrowser_scope(options)
  end


  def ckeditor_before_create_asset(asset)
    asset.assetable = Column.find(params[:column_id])
    return true
  end

我希望它可以对其他人有所帮助。

答案 3 :(得分:-1)

您要搜索的是使用多态图片模型,它将属于许多其他模型。

请在这里阅读http://rails-bestpractices.com/posts/45-use-sti-and-polymorphic-model-for-multiple-uploads,因为它描述得非常好。