error: undefined method `presigned_post' - ruby-on-rails

I'm writing a rails application with which a user can upload images. I am deploying with Heroku, and using Carrierwave and S3 to upload and store images. I have followed this heroku guide step-by-step...unfortunately I am still getting an error "undefined method `presigned_post'", and do not know how to resolve it. It seems the S3_BUCKET is not being recognized as an aws object...
Has anyone come across this problem and figured it out? Here's some code for reference:
Pictures controller:
class PicturesController < ApplicationController
before_action :set_s3_direct_post, only: [:new, :create]
def index
#pictures = Picture.all
end
def new
#pictures = Picture.all
#picture = Picture.new
end
def create
#picture = Picture.new(picture_params)
if #picture.save
redirect_to new_picture_path, notice: "You just uploaded a picture!"
else
render "new"
end
end
...
def picture_params
params.require(:picture).permit(:attachment)
end
private
def set_s3_direct_post
#s3_direct_post = S3_BUCKET.presigned_post(key: "uploads/#{SecureRandom.uuid}/${filename}", success_action_status: '201', acl: 'public-read')
end
end
New picture view:
<h1>Upload a new picture</h1>
<br>
<div class="well">
<%= form_for #picture, html: { class: 'directUpload', data: { 'form-data' => (#s3_direct_post.fields), 'url' => #s3_direct_post.url, 'host' => URI.parse(#s3_direct_post.url).host } } do |f| %>
<%= f.file_field :attachment %>
<%= f.submit "Upload", class: "btn btn-default" %>
<% end %>
</div>
And config/environment.rb:
require File.expand_path('../application', __FILE__)
# Initialize the Rails application.
Rails.application.initialize!
# S3
S3_BUCKET='fotoes'
AWS_ACCESS_KEY_ID='secretxxxxxxxx'
AWS_SECRET_ACCESS_KEY='xxxxxxxsecretxxxxxx'
Any thoughts?

#Jillian I suppose your expectation was that S3_BUCKET class should call presigned_post method which is supposed to be defined. However, it seems its not. I took a look at the heroku page containing the tutorial you followed and well you followed every instruction. I suggest you contact heroku about the documentation. However, I would keep looking into it

Thank you all for your help. In the end I found a different walk-through that was much simpler and effective. (The Heroku one was a little complicated and left a lot to go wrong - go figure.)
This solved everything :)
edit:
not everything - had to complete one last step before I got the site running. Run this line in the terminal: $ heroku config:add AWS_ACCESS_KEY=value
and $ heroku config:add AWS_SECRET_KEY=value, where the value is your S3 credentials for each, respectively.
This was the only combo of fog, carrierwave, rails, fog-aws gems that worked (after weeks of fussing with them):
gem 'rails', '4.1.0'
gem 'carrierwave', '~> 0.10.0'
gem 'fog', '1.34.0'
gem 'fog-aws', '0.7.6'

i resolved this by updating my version of aws-sdk
$ bundle update aws-sdk

Related

Rails form_tag not POSTing, GETing on the source page

It's been a while since I've needed anything but a form_for.
Now I'm trying to set up an admin area search where the search box is in the menu bar. But instead of POSTing to the results path it's reloading the existing page with GET params, including the authenticity_token.
So my set up:
Gemfile
source 'https://rubygems.org'
ruby '2.2.3'
gem 'rails', '4.2.3'
# And so on....
routes.rb
namespace :admin do
resources :results do #search results
collection do
get :display
end
end
# many more routes here
end
admin/results_controller.rb
class Admin::ResultsController < ApplicationController
def display
#results = Elasticsearch::Model.search(params[:query], [Article]).paginate(page: params[:page], per_page: 30)
respond_to do |format|
format.html # index.html.erb
end
end
private
# Don't think this is really relevant, adding out of desparation
def result_params
params.require(:result).permit(:query)
end
end
And in my universal admin bar:
<%= form_tag(display_admin_results_path, method: :post) do %>
<%= text_field_tag :query, params[:query], {class: "form-control", placeholder: "Search"} %>
<span class="input-group-btn"><%= submit_tag "→".html_safe, class: "btn btn-success" %></span>
<% end %>
Logs show no sign of a redirection, Chome console shows no javascript "bork."
Instead of submitting that form and getting sent to /admin/results/display or even /admin/results/display?query=blah I'm gettting
?utf8=✓&authenticity_token=j3w4dtBbFLzJzqWGZ9x4Q4GsUi%2FxmjYFrPjdzm8ccLKdxpOR0KwrX2hIAzXkR96cuTVgwG1sbYBKDdSO%2F3O6Wg%3D%3D&query=hello&commit=→
It's got to be something obvious... prepared for the 'doh' moment.
The problem is in your routes.
In your console write rails routes (or rake routes), and you will see that it expects get method for your display_admin_results_path. So you access your controller with GET method.
your routes:
display_admin_results GET /admin/results/display(.:format) admin/results#display
admin_results GET /admin/results(.:format) admin/results#index
POST /admin/results(.:format) admin/results#create
admin_result GET /admin/results/:id(.:format) admin/results#show
PATCH /admin/results/:id(.:format) admin/results#update
PUT /admin/results/:id(.:format) admin/results#update
DELETE /admin/results/:id(.:format) admin/results#destroy
You should implement your search query, so that it will use POST, and return corresponding view(which is defenetly not index).
Also, you render method searches the view with coresponding name, so you may want to create display.html.erb file, or specify the view you want to use in controller.

undefined local variable or method verify_recaptcha

I am following the this to implement captcha, but I am stuck at last step. Here is my controller:
bug_report = BugReport.new(bug_report_params)
if verify_recaptcha
if bug_report.valid?
bug_report.save!
#render success
else
#throw error
end
else
#Invalid captcha
end
I am getting error saying: undefined local variable or method verify_recaptcha
Other codes are here:
view
<%= form_for :bug_report, url: bug_reports_path do |f| %>
<%= recaptcha_tags %>
<%= f.submit 'Submit' %>
<% end %>
gemfile
gem "recaptcha", :require => "recaptcha/rails"
recaptcha.rb
Recaptcha.configure do |config|
config.public_key = 'publik_key_here'
config.private_key = 'private_key_here'
end
I am getting the following data in params:
{
utf8: "✓",
g-recaptcha-response: "Long text here",
commit: "Submit",
controller: "api/v1/bug_reports",
action: "index"
}
Please guide me, how to fix it.
From your comments, It looks like you have the rails app with config.api_only = true set in application.rb. For a list of what it actually does, check this documentation.
One consequence of this is ApplicationController would inherit from ActionController::API instead of ActionController::Base. But if you look at recaptcha's source code, the include is on ActionController::Base.
So, you can directly include Recaptcha::Verify module in your ApplicationController.
# app/controllers/application_controller.rb
class ApplicationController < ActionController::API
include Recaptcha::Verify
...
end

RoR HTML template to .docx

I need to create a .docx file from a HTML template, so I used htmltoword gem.
Usage:
I added the gem (Gemfile):
gem 'htmltoword', '~> 0.5.1' #last version of the gem
I put a route (route.rb):
get 'preview' => 'foo#preview'
And in my bar.html.erb I have a link which target's that url:
<%= link_to '.docx', preview_path %>
Template (preview.docx.erb):
<h1>foobar</h1>
And in the controller (foos_controller.rb):
class FoosController < ApplicationController
respond_to :docx
#other code
def preview
respond_to do |format|
format.docx do
render docx: 'foobar', filename: 'preview.docx'
end
end
end
end
However, I'm getting an error:
ActionController::UnknownFormat
How to fix this error?
My config:
RoR v4.2.4
Ruby v2.2.3p173
Also, there is an open github issue for this/similar topic.
Update: as #kajalojha mentioned, respond_with / Class-Level respond_to has been removed to an individual gem, so I installed the responders gem, however, I get the same error.
Since respond_to has been removed from rails 4.2 to a individual gem i will recommend you to use formatter gem..
For further details you can look to the link given below.
Why is respond_with being removed from rails 4.2 into it's own gem?
Have you tried caracal-rails? You can find it here
I had to build this same functionality in an app earlier this year and also used the htmltoword gem.
# At the top of the controller:
respond_to :html, :js, :docx
def download
format.docx {
filename: "#{dynamically_generated_filename}",
word_template: 'name_of_my_word_template.docx')
}
end
I then have two "view" files that come into play. The first, is my method view file download.docx.haml. This file contains the following code:
%html
%head
%title Title
%body
%h1 A Cool Heading
%h2 A Cooler Heading
= render partial: 'name_of_my_word_template', locals: { local_var: #local_var }
From there, I have another file name_of_my_word_template.docx.haml that contains the meat of my Word file.
%h4 Header
%h5 Subheader
%div= local_var.method
%div Some other content
%div More content
%div Some footer content
When someone hits my_app.com/controller_name/download.docx, a Word file is generated and downloaded for them.
In order to ensure this happens, I have a route for the download method in my routes.rb file:
resources :model_name do
member do
get :download
end
end
Apologies for the long reply ... this has worked well for me and I hope helps you through this issue!
So, I figured it out. I added format: 'docx' to the route and it works now.
Note: as #kajalojha mentioned, respond_with / Class-Level respond_to has been removed to an individual gem, so I installed the responders gem.
Let's create a download logic.
Gemfile
gem 'responders'
gem 'htmltoword', '~> 0.5.1'
routes.rb
get 'download' => 'foos#download', format: 'docx' #added format
foos_controller.rb
class FoosController < ApplicationController
respond_to :docx
def download
#bar = "Lorem Ipsum"
respond_to do |format|
format.docx do
# docx - the docx template that you'll use
# filename - the name of the created docx file
render docx: 'download', filename: 'bar.docx'
end
end
end
end
download.docx.erb
<p><%= #bar %></p>
And I've added some link to trigger the download logic:
<%= link_to 'Download bar.docx', foo_download_path %>
Which will download the bar.docx file with "Lorem Ipsum" in it.

Running faye on heroku using Rails 4 not working

I am trying to implement a chat feature in my rails app deployed on heroku . For this I have created two rails apps one my original app and the other to acts as faye server.
I have given the faye app url in my original app to create faye server object.
Following is what I have added in my original app:
Ruby version: 2.0.0
gemfile
gem 'thin'
gem 'faye'
gem 'rails', '4.1.5'
Application.rb
<%= javascript_include_tag 'http://xxx.herokuapp.com/faye.js' %>
Application.js
$(function(){
$(document).foundation();
var faye = new Faye.Client('http://xxx.herokuapp.com/faye');
faye.subscribe("/messages/new", function(data) {
eval(data);
});
});
Message Helper
def broadcast(channel, &block)
message = {:channel => channel, :data => capture(&block)}
uri = URI.parse("http://xxx.herokuapp.com/faye")
Net::HTTP.post_form(uri, :message => message.to_json)
end
Message Controller
class MessagesController < ApplicationController
def index
#messages = Message.all
end
def create
#message = Message.create!(message_params)
end
private
def message_params
params.require(:message).permit(:content)
end
end
My View:
messages/create.js.erb
<% broadcast "/messages/new" do %>
$("#chat").append("<%= escape_javascript render(#message) %>");
<% end %>
$("#new_message")[0].reset();
/messages/index.html.erb
<ul id="chat">
<%= render #messages %>
</ul>
<%= form_for Message.new, :remote => true do |f| %>
<%= f.text_field :content %>
<%= f.submit "Send" %>
<% end %>
Follwing is what I added in my faye server app:
faye.ru
require 'faye'
Faye::WebSocket.load_adapter('thin')
app = Faye::RackAdapter.new(:mount => '/faye', :timeout => 25)
run app
Procfile
web: bundle exec thin -p $PORT -e $RACK_ENV -R faye.ru start
I am getting a 500 internal sever error whenever I try to send a message. The code is working fine on local. Also I am getting Error during WebSocket handshake: Unexpected response code: 404 in chrome. I tried enabling cors but that did not helped either.
Note: Below are some reference links which are not working for me
Using rails sync gem with Faye and Thin in production mode on Heroku
https://blog.heroku.com/archives/2013/10/8/websockets-public-beta
This is not working heroku labs:enable websockets
I am new for heroku and faye.

Rails creating malformed routes with dots

I'm using the path helper methods to generate URLs in link_to, and they are returning URLs formated like this :
http://localhost:3000/tweets.4
when I was expecting them to be formated like this:
http://localhost:3000/tweets/4
Note how it is using a dot as the delimiter instead of the expected forward slash. The top link doesn't resolve to the correct view, it simply reloads the /tweets view. When I manually edit the URL to be like the bottom, it opens the correct /tweets/show/.
The closest thing I found in my online research was that people encountered this with wrongly nested routing statements - but I don't think I'm doing that here.
I would appreciate any help or pointers anyone can provide!
Here are the related source files and version information :
tweets/index.html.erb
<h1>Listing tweets</h1>
<% #tweets.each do |tweet| %>
<div>
<!-- creates path in format of /tweets.2 -->
<div><%= link_to tweet.status, tweets_path(tweet) %></div>
<!-- creates path in the format of /user.1 -->
<div><%= link_to tweet.user.name, users_path(tweet.user) %></div>
</div>
<% end %>
tweets_controller.rb
class TweetsController < ApplicationController
def index
#tweets = Tweet.all
end
def show
#tweet = Tweet.find(params[:id])
end
def new
#tweet = Tweet.new
end
def create
#tweet = Tweet.new(params[:tweet])
#tweet.user = User.last
if(#tweet.save)
redirect_to :root
end
end
def edit
#tweet = Tweet.find(params[:id])
end
def delete
end
end
routes.rb
Zombietweets::Application.routes.draw do
resources :tweets
root :to => 'tweets#index'
end
Gemfile
source 'https://rubygems.org'
gem 'rails', '3.2.9'
group :development, :test do
gem 'sqlite3', '1.3.5'
gem 'rspec-rails', '2.11.0'
end
group :assets do
gem 'sass-rails', '3.2.3'
gem 'coffee-rails', '3.2.1'
gem 'uglifier', '1.0.3'
end
gem 'jquery-rails', '2.0.2'
I'm using Rails 3.2.9 and Ruby 1.9.3p327 (2012-11-10) [x86_64-darwin12.2.0]
Have you tried tweet_path and user_path ?
You want to access the show action. For that action, the model name must be singular in the *_path call.
To be sure, try a rake routes in a console.
EDIT:
You also forget to add resources :users in your routes file :)

Resources