Reputation: 4306
I've been wracking my brain for hours pouring over documentation and I can not for the life of me figure out what's wrong. The form is accepting an image, but does not trigger a direct upload. My files below.
Gemfile
source 'https://rubygems.org'
# Platform
gem 'rails', '4.2.6'
# Authentication / Authorization
gem 'devise'
# View Tools
gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'haml-rails'
gem 'font-awesome-rails'
gem 'friendly_id', '~> 5.1.0'
# Form
gem 'cocoon'
gem 'ckeditor'
gem 'mini_magick'
# DB Tools
gem 'pg'
gem 'seed_dump'
gem 'annotate'
# Image Serving & Uploading
gem 'carrierwave'
gem 'cloudinary'
# Server Tools
gem 'puma'
gem 'foreman'
gem 'turbolinks'
gem 'rails_12factor' # To silence Heroku deprecation warning
# Gems used only for assets and not required in production environments by default.
gem 'sassc-rails'
gem 'uglifier'
group :development do
gem 'web-console', '~> 2.0'
gem 'awesome_print', :require => 'ap'
gem 'better_errors'
gem 'binding_of_caller'
gem 'meta_request'
end
application.js
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require bootstrap.min
//= require cloudinary
//= require cocoon
//= require turbolinks
//= require_tree .
scripts.js
$(function() {
if($.fn.cloudinary_fileupload !== undefined) {
$("input.cloudinary-fileupload[type=file]").cloudinary_fileupload();
}
});
application.haml
!!!
%html
%head
%meta{:charset => "utf-8"}
%meta{:content => "IE=edge", "http-equiv" => "X-UA-Compatible"}
%meta{:content => "width=device-width, initial-scale=1", :name => "viewport"}/
%title Martin Furniture
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
= javascript_include_tag 'application', 'data-turbolinks-track' => true
= csrf_meta_tags
= cloudinary_js_config
%link{:href => "https://fonts.googleapis.com/css?family=Open+Sans|Oswald", :rel => "stylesheet"}
%body
= render :partial => 'layouts/partials/header'
= yield
= render :partial => 'layouts/partials/footer'
image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
include Cloudinary::CarrierWave
end
figure.rb
# == Schema Information
#
# Table name: figures
#
# id :integer not null, primary key
# caption :string(255)
# link :text
# figureable_id :integer
# figureable_type :string
# created_at :datetime not null
# updated_at :datetime not null
# title :string(255)
# alt :string(255)
# image :string
#
class Figure < ActiveRecord::Base
default_scope { order(id: :ASC) }
mount_uploader :image, ImageUploader
# Figureable (Polymorphic)
# ==========================================================================================================
belongs_to :figureable,
polymorphic: true
end
page.rb
# == Schema Information
#
# Table name: pages
#
# id :integer not null, primary key
# name :string(255) not null
# slug :string
# created_at :datetime not null
# updated_at :datetime not null
# template_id :integer default(1), not null
# title :string(255)
# content :text
# link :text
# parent_id :integer
#
class Page < ActiveRecord::Base
default_scope { order(id: :ASC) }
extend FriendlyId
friendly_id :name, use: :slugged
# Figures (Polymorphic)
# ==========================================================================================================
has_many :figures,
as: :figureable
accepts_nested_attributes_for :figures,
reject_if: :all_blank,
allow_destroy: true
# Validations
# ==========================================================================================================
validates :name,
presence: true,
format: { with: /[0-9a-zA-Z\s\/_:\-.|]*/ }
end
figures_controller.rb
class FiguresController < ApplicationController
before_action :set_figure, only: [:show, :edit, :update, :destroy]
def index
@figures = Figure.all
end
def show
end
def new
@figure = Figure.new
end
def edit
end
def create
@figureable = find_figureable
if @figurable
@figure = @figureable.figures.build(figure_params)
else
@figure = Figure.new(figure_params)
end
if @figure.save
redirect_to @figure, notice: 'Figure was successfully created.'
else
render :new
end
end
def update
if @figure.update(figure_params)
redirect_to @figure, notice: 'Figure was successfully updated.'
else
render :edit
end
end
def destroy
@figure.destroy
redirect_to figures_url, notice: 'Figure was successfully destroyed.'
end
private
def set_figure
@figure = Figure.find(params[:id])
end
def figure_params
params.require(:figure).permit(:caption, :link, :figurable_id, :figurable_type)
end
def find_figureable
params.each do |name, value|
if name =~ /(.+)_id$/
return = $1.classify.constantize.find(value)
end
end
nil
end
end
pages_controller.rb
class PagesController < ApplicationController
before_action :set_page, only: [:edit, :update, :destroy]
# GET /pages
def index
@pages = Page.all.reorder(slug: :ASC)
end
# GET /pages/1
def show
@page = Page.friendly.find(params[:id])
page_template = "layouts/templates/#{@page.name.parameterize.underscore}"
if lookup_context.find_all(page_template).any?
render page_template
else
render :show
end
end
# GET /pages/new
def new
@page = Page.new
end
# GET /pages/1/edit
def edit
end
# POST /pages
def create
@page = Page.new(page_params)
if @page.save
redirect_to pages_url, notice: 'Page was successfully created.'
else
render :new
end
end
# PATCH/PUT /pages/1
def update
if @page.update(page_params)
redirect_to pages_url, notice: 'Page was successfully updated.'
else
render :edit
end
end
# DELETE /pages/1
def destroy
@page.destroy
redirect_to pages_url, notice: 'Page was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_page
@page = Page.friendly.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def page_params
params.require(:page)
.permit(
:name,
:slug,
:template_id,
:title,
:content,
:link,
# belongs_to
:parent_id,
# has_many (Nested Attributes)
{ :figures_attributes => [
:_destroy,
:id,
:caption,
:link,
:title,
:alt,
:image
]},
)
end
end
pages/_form.haml
= form_for @page do |f|
- if @page.errors.any?
#error_explanation
%h2= "#{pluralize(@page.errors.count, "error")} prohibited this page from being saved:"
%ul
- @page.errors.full_messages.each do |msg|
%li= msg
.field
= f.label :name
= f.text_field :name
%h3 Figures
#figures
= f.fields_for :figures do |figure|
= render 'figures/figure_fields', f: figure
.links
= link_to_add_association 'Add Figure', f, :figures, partial: 'figures/figure_fields'
.field
= f.cktext_area :content
.actions
= f.submit 'Save'
figures/_figure_fields.html
.nested-fields
.field
= f.label :caption
= f.text_field :caption
.field
= f.label :link
= f.text_field :link
.field
= f.label :image, "Image"
= f.cl_image_upload :image
= link_to_remove_association "Remove Figure", f
params upon form submission
Processing by PagesController#create as HTML
20:43:40 web.1 | Parameters: {"utf8"=>"✓", "authenticity_token"=>"AUTHENTICITY_TOKEN", "page"=>{"name"=>"Blah2", "figures_attributes"=>{"1471318988746"=>{"caption"=>"B", "link"=>"C", "_destroy"=>"false"}}, "content"=>""}, "file"=>"main_image.jpg", "commit"=>"Save"}
rendered input element
<input type="file" name="file" data-url="https://api.cloudinary.com/v1_1/CLOUD_NAME/auto/upload" data-form-data="{"callback":"http://localhost:8080/cloudinary_cors.html","timestamp":1471319573,"signature":"SIGNATURE","api_key":"API_KEY"}" data-cloudinary-field="page[figures_attributes][1471319575584][image]" class="cloudinary-fileupload">
cloudinary.yml
---
#Production MF
development:
cloud_name: CLOUD_NAME
api_key: 'API_KEY'
api_secret: SECRET_KEY
enhance_image_tag: true
static_image_support: false
production:
cloud_name: CLOUD_NAME
api_key: 'API_KEY'
api_secret: SECRET_KEY
enhance_image_tag: true
static_image_support: true
test:
cloud_name: CLOUD_NAME
api_key: 'API_KEY'
api_secret: SECRET_KEY
enhance_image_tag: true
static_image_support: false
*Note the above CLOUD_NAME
, API_KEY
, SIGNATURE
, AUTHENTICITY_TOKEN
AND SECRET_KEY
are filled out with the correct information, but have been removed for this post. Additionally, the cloudinary_cores.html
file is in my public
directory.
I've tried following the instructions both on the Cloudinary Gems repo and on their help docs and can not figure out what the problem is.
If there's anything else anyone needs, please let me know.
Upvotes: 0
Views: 499
Reputation: 4306
So, it turns out that the turbolinks
gem was the culprit here. By changing scripts.js
to the following, I'm now uploading properly.
Note: This is the usage for Turbolinks 5
- Previous versions require a slightly different setup.
scripts.js
// jQuery "$(document).ready()" equivalent for Trubolinks 5 usage
$(document).on('turbolinks:load', function() {
console.log("trubolinks:load - jQuery Ready!");
$(function() {
cloudinaryUploaderInit();
});
});
var cloudinaryUploaderInit = function() {
// console.log("cloudinaryUploaderInit");
if ($.fn.cloudinary_fileupload !== undefined) {
$("input.cloudinary-fileupload[type=file]").each(function() {
$(this).cloudinary_fileupload();
});
} else {
// console.log("`cloudinary_fileupload` is undefined");
}
}
EDIT: Alternatively (and prehaps more approproately), you can use the jquery-turbolinks
gem as outlined here: https://github.com/cloudinary/cloudinary_gem/issues/126
Upvotes: 1