So in my course on Coursera I'm required to build this rather simple aplication to obtain and display an array from an external api. I'm using the ruby on rails framework. (I'm using windows 10)
Controller -
class CoursesController < ApplicationController
def index
#search_term = params[:looking_for] || 'jhu'
#courses = Coursera.for(#search_term)
end
end
Model
class Coursera
include HTTParty
default_options.update(verify: false) # Turn off SSL verification
base_uri 'https://api.coursera.org/api/courses.v1'
default_params fields: "photoUrl,description",q: "search"
format :json
def self.for term
get("",query: {query: term}) ["elements"]
end
end
The view is irrelevant as this works fine.
But in my other app , I get this error -
Errno::ECONNREFUSED: Failed to open TCP connection to :80 (Connection refused - connect(2) for nil port 80)
This is the other app which I'm having the problem with -
Controller -
class RecipesController < ApplicationController
def index
#search_term = params[:search] || 'chocolate'
#recipes = Recipe.for #search_term
end
end
Model -
class Recipe
include HTTParty
default_options.update(verify: false) # Turn off SSL verification
key_value = ENV['FOOD2FORK_KEY']
hostport = ENV['FOOD2FORK_SERVER_AND_PORT'] || 'food2fork.com'
base_uri = "https://doesntmatter.com/api" #website mentioned here
#doesn't matter , I get the error nonetheless
default_params key: ENV['FOOD2FORK_KEY'] ,q: "search"
format :json
def self.for term
get("/search",query: {query: term}) ["recipes"]
end
end
I've tried disabling all possible firewalls , unblocked all ports with TCP in windows firewall , but I still get the same error. Any ideas how to fix this ? Because I don't think its a problem in my code yet...
You have an excess symbol in your code:
class Recipe
# some code here
base_uri = "https://doesntmatter.com/api"
^ # the equal symbol is redundant.
# remove it and all will works as expected
# ....
end
Related
I am upgrading my Rails app from 4.1.1 to 5.1.4.
I am using roar-rails gem to parsing and rendering REST documents. I am facing some issues as responders gem has been extracted to separate gem.
respond_with has been moved to 'responders' gem.
My rails 4 code lookgs like this:
PostsController:
class PostsController < ApplicationController
respond_to :json
def index
posts = current_user.posts
respond_with posts, :represent_with => PostsRepresenter, current_user: current_user
end
end
My representers for Post
module PostsRepresenter
# Rails 4 code
# include Roar::Representer::JSON::HAL
# Rails 5 code (after adding responders) --------
include Roar::JSON
include Roar::Hypermedia
# Rails 5 code --------
collection(
:post,
class: Post,
extend: PostRepresenter,
embedded: true)
link :make do |args|
p "............. #{args.inspect}"
# In rails 4, args are coming correctly what is passing from Controller
# But in rails 5, args is coming `nil`
posts_path if args[:current_user].can_create?(Post)
end
end
Post representer
module PostRepresenter
# Rails 4 code
# include Roar::Representer::JSON::HAL
# Rails 5 code (after adding responders) --------
include Roar::JSON
include Roar::Hypermedia
# Rails 5 code --------
property :title
property :description
property :author
link :self do |args|
post_path(id) if args[:current_user].can_read?(self)
end
link :remove do |args|
post_path(id) if args[:current_user].can_delete?(self)
end
link :edit do |args|
post_path(id) if args[:current_user].can_update?(self)
end
end
I am facing issue with args which are passing through Controller,
after rails 5, its coming nil.
I have debug the issue and found that in responders gem, options are coming in respond_with method, but I think it could not send it to roar-rails.
/path-to-gem/vendor/responders-master/lib/action_controller/respond_with.rb
Here is snippet:
def respond_with(*resources, &block)
if self.class.mimes_for_respond_to.empty?
raise "In order to use respond_with, first you need to declare the " \
"formats your controller responds to in the class level."
end
mimes = collect_mimes_from_class_level
collector = ActionController::MimeResponds::Collector.new(mimes, request.variant)
block.call(collector) if block_given?
if format = collector.negotiate_format(request)
_process_format(format)
options = resources.size == 1 ? {} : resources.extract_options!
options = options.clone
options[:default_response] = collector.response
p "====================== options :: #{options.inspect}"
# Options are correct till here but coming `nil` on representers
(options.delete(:responder) || self.class.responder).call(self, resources, options)
else
raise ActionController::UnknownFormat
end
end
Please let me know what needs to be done here that make args
available in representers
respond_with was deprecated from rails 4.2.1.
https://apidock.com/rails/ActionController/MimeResponds/respond_with
I have Ember.js client and RoR server side with gem "websocket-rails".
I need to get private channel with authorization to send messages only for one user.
This is how I try:
class AuthorizationController < WebsocketRails::BaseController
before_action :require_login
def authorize_channels
# The channel name will be passed inside the message Hash
puts '*'*400
ap current_user//Here I see the user
channel = WebsocketRails[message[:channel]]
accept_channel current_user
end
def require_login
sign_in(User.find(4))
end
end
My events.rb is:
WebsocketRails::EventMap.describe do
namespace :websocket_rails do
subscribe :subscribe, :to => AuthorizationController, :with_method => :authorize_channels
end
end
But when I try to send message with:
WebsocketRails.users[4].trigger(:test_event, { message: 'This is a private message from WebSocket Rails' } )
I get error #<NoMethodError: undefined method ``trigger' for #<WebsocketRails::UserManager::MissingConnection:0x007ff5bb50dc88>>
And if I try to print WebsocketRails.users I see:
#<WebsocketRails::UserManager:0x007ff5bb617d68 #users={}>
What is wrong?
Thx a lot!
If u use rails-api gem, it disables a session, that was the problem.
We have a custom exception app that has been raising (fail safe) exceptions (the application equivalent of having an exception in a rescue block).
I think I've fixed it, but am finding it hard to test. It's an unrouted controller, so I can't use controller tests (require routing).
i.e. I have Rails.configuration.exceptions_app = ExceptionController.action(:show), not Rails.configuration.exceptions_app = self.routes.
Basically what I think I need to do is
Generate a test request request = ActionDispatch::TestRequest.new
include Rack::Test or maybe mimic behavior in ActiveSupport::IntegrationTest
Set #app = ExceptionsController.action(:show)
Fake an exception request.env.merge! 'action_dispatch.exception' => ActionController::RoutingError.new(:foo)
Test response = #app.call(request.env)
Assert no exception is raised and correct response body and status
Problems:
The env needs
a warden / devise session with current_user request.env['warden'] = spy(Warden) and request.session = ActionDispatch::Integration::Session.new(#app)
to manipulate request formats so that I can check that a request without an accept defaults to json request.any?(:json)? constraints: { default: :json } ? `request.accept = "application/javascript"
work work with the respond_with responder
set action_dispatch.show_exceptions, consider all requests local, etc request.env["action_dispatch.show_detailed_exceptions"] = true
Also, I considered building a ActionDispatch::ShowException.new(app, ExceptionController.new) or a small rack app
But our gem has no tests and I haven't been able to apply anything that I've read in exception handling gems (most work at the rescue_action_in_public level or mix in to ShowException) or in the Rails source code
This is a Rails 4.2 app tested via Rspec and Capybara.
Thoughts, links, halp?
Example code and tests
RSpec.describe 'ExceptionController' do
class ExceptionController < ActionController::Base
use ActionDispatch::ShowExceptions, Rails.configuration.exceptions_app
use ActionDispatch::DebugExceptions
#Response
respond_to :html, :json
#Layout
layout :layout_status
#Dependencies
before_action :status, :app_name, :log_exception
def show
respond_with details, status: #status, location: nil
end
def show_detailed_exceptions?
request.local?
end
protected
####################
# Dependencies #
####################
#Info
def status
#exception = env['action_dispatch.exception']
#status = ActionDispatch::ExceptionWrapper.new(env, #exception).status_code
#response = ActionDispatch::ExceptionWrapper.rescue_responses[#exception.class.name]
end
#Format
def details
#details ||= {}.tap do |h|
I18n.with_options scope: [:exception, :show, #response], exception_name: #exception.class.name, exception_message: #exception.message do |i18n|
h[:name] = i18n.t "#{#exception.class.name.underscore}.title", default: i18n.t(:title, default: #exception.class.name)
h[:message] = i18n.t "#{#exception.class.name.underscore}.description", default: i18n.t(:description, default: #exception.message)
end
end
end
helper_method :details
####################
# Layout #
####################
private
def log_exception
if #status.to_s == '500'
request.env[:exception_details] = details
request.env[:exception_details][:location] = ActionDispatch::ExceptionWrapper.new(env, #exception).application_trace[0]
end
end
#Layout
def layout_status
#status.to_s != '404' ? 'error' : 'application'
end
#App
def app_name
#app_name = Rails.application.class.parent_name
end
end
include Rack::Test::Methods
include ActionDispatch::Integration::Runner
include ActionController::TemplateAssertions
include ActionDispatch::Routing::UrlFor
let(:exception) { ActionController::RoutingError.new(:foo) }
let(:request) { ActionDispatch::TestRequest.new }
def app
# Rails.application.config.exceptions_app
#app ||= ExceptionController.action(:show)
end
it 'logs unknown format errors' do
request.env['action_dispatch.show_exceptions'] = true
request.env['consider_all_requests_local'] = true
request.env['warden'] = spy(Warden)
request.session = ActionDispatch::Integration::Session.new(app)
exception = ActionController::RoutingError.new(:foo)
request.env.merge! 'action_dispatch.exception' => exception
post '/whatever'
expect(response.body).to eq("dunno?")
end
end
refs:
https://github.com/richpeck/exception_handler
https://github.com/plataformatec/responders/blob/8f03848a2f50d4685c15a31254a1f600af947bd7/test/action_controller/respond_with_test.rb#L265-L275
https://github.com/rails/rails/blob/1d43458c148f9532a81b92ee3a247da4f1c0b7ad/actionpack/test/dispatch/show_exceptions_test.rb#L92-L99
https://github.com/rails/rails/blob/3e36db4406beea32772b1db1e9a16cc1e8aea14c/railties/test/application/middleware/exceptions_test.rb#L86-L91
https://github.com/rails/rails/blob/34fa6658dd1b779b21e586f01ee64c6f59ca1537/actionpack/lib/action_dispatch/testing/integration.rb#L647-L674
https://github.com/rails/rails/blob/ef8d09d932e36b0614905ea5bc3fb6af318b6ce2/actionview/test/abstract_unit.rb#L146-L184
https://github.com/plataformatec/responders/blob/8f03848a2f50d4685c15a31254a1f600af947bd7/lib/action_controller/respond_with.rb#L196-L207
http://blog.plataformatec.com.br/2012/01/my-five-favorite-hidden-features-in-rails-3-2/
https://github.com/bugsnag/bugsnag-ruby/blob/master/lib/bugsnag/middleware/warden_user.rb
https://github.com/bugsnag/bugsnag-ruby/blob/master/lib/bugsnag/rails/action_controller_rescue.rb#L3-L33
https://github.com/bugsnag/bugsnag-ruby/blob/master/lib/bugsnag/rails/active_record_rescue.rb
https://github.com/rollbar/rollbar-gem/blob/master/spec/rollbar_spec.rb
http://andre.arko.net/2011/12/10/make-rails-3-stop-trying-to-serve-html/
https://github.com/rails/rails/blob/9503e65b9718e4f01860cf017c1cdcdccdfffde7/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L46-L49
Update 2015-08-27
It has been suggested that this question may be a duplicate of Testing error pages in Rails with Rspec + Capybara, however, that question addresses testing exception responses when the exceptions_app is set to routes.
As I wrote above, I'm using a Controller as the exceptions_app, so though I could use capybara to visit non-existing pages, I'd like to test Controller's action directly, rather than include the rest of the show exceptions stack. This is important because my problem is when the exceptions app is called with an unhandled content type, which I cannot easily test via capybara.
More generally, what I need to test is when the Exceptions app raises and exception, that I have fixed it.
I'm open to seeing some example code, though.
I'm working with a team on checking a user's email input when they sign up for a web app. The user will not be allowed to sign up if their email is not found with the following API call using HTTParty. We are getting method_errors for whatever syntax is first within the function. For, example, in the method below, "include" comes up as an undefined method error.
def email_checker
include HTTParty
default_params :output => 'json'
format :json
base_uri 'app.close.io'
basic_auth 'insert_api_code_here', ' '
response = HTTParty.get('/api/v1/contact/')
#email_database = []
response['data'].each do |x|
x['emails'].each do |contact_info|
#email_database << contact_info['email']
end
end
unless #email_database.include? :email
errors.add :email, 'According to our records, your email has not been found!'
end
end
UPDATE: So we went with the inline version of using HTTParty and our registrations controller (working with devise) looks like this:
class RegistrationsController < Devise::RegistrationsController
def email_checker(email)
YAML.load(File.read('config/environments/local_env.yml')).each {|k, v| ENV[k.to_s] = v}
api_options = {
query: => {:output => 'json'},
format: :json,
base_uri: 'app.close.io',
basic_auth: ENV["API_KEY"], ' '
}
response = HTTParty.get('/api/v1/contact/', api_options)
#email_database = []
response['data'].each do |x|
x['emails'].each do |contact_info|
#email_database << contact_info['email']
end
end
unless #email_database.include? email
return false
else
return true
end
end
def create
super
if email_checker == false
direct_to 'users/sign_up'
#and return to signup with errors
else
User.save!
end
end
end
We're getting syntax error: "syntax error, unexpected =>" Did we screw up the format?
There are two different ways to use HTTParty, and you're trying to use both. Pick one :).
The class-based method would look something like this:
class CloseIo
include HTTParty
default_params :output => 'json'
format :json
base_uri 'app.close.io'
basic_auth 'insert_api_code_here', ' '
end
class UserController
def email_checker
response = CloseIo.get('/api/v1/contact/')
# ... the rest of your stuff
end
end
An inline version would look something like this
class UserController
def email_checker
api_options = {
query: :output => 'json',
format: :json,
base_uri: 'app.close.io',
basic_auth: 'insert_api_code_here'
}
response = HTTParty.get('/api/v1/contact/', api_options)
# ... do stuff
end
end
I can't get geocoder to work correct as my local ip address is 127.0.0.1 so it can't located where I am correctly.
The request.location.ip shows "127.0.0.1"
How can I use a different ip address (my internet connection ip) so it will bring break more relevant data?
A nice clean way to do it is using MiddleWare. Add this class to your lib directory:
# lib/spoof_ip.rb
class SpoofIp
def initialize(app, ip)
#app = app
#ip = ip
end
def call(env)
env['HTTP_X_FORWARDED_FOR'] = nil
env['REMOTE_ADDR'] = env['action_dispatch.remote_ip'] = #ip
#status, #headers, #response = #app.call(env)
[#status, #headers, #response]
end
end
Then find an IP address you want to use for your development environment and add this to your development.rb file:
config.middleware.use('SpoofIp', '64.71.24.19')
For this I usually use params[:ip] or something in development. That allows me to test other ip addresses for functionality and pretend I'm anywhere in the world.
For example
class ApplicationController < ActionController::Base
def request_ip
if Rails.env.development? && params[:ip]
params[:ip]
else
request.remote_ip
end
end
end
I implemented this slightly different, and this works well for my case.
In application_controller.rb i have a lookup method which calls the Geocoder IP lookup directly passing in the results of request.remote_ip.
def lookup_ip_location
if Rails.env.development?
Geocoder.search(request.remote_ip).first
else
request.location
end
end
Then in config/environments/development.rb i monkey-patched the remote_ip call:
class ActionDispatch::Request
def remote_ip
"71.212.123.5" # ipd home (Denver,CO or Renton,WA)
# "208.87.35.103" # websiteuk.com -- Nassau, Bahamas
# "50.78.167.161" # HOL Seattle, WA
end
end
I just hard code some addresses, but you could do whatever you'd like here.
I had the same question. Here is how I implemented with geocoder.
#gemfile
gem 'httparty', :require => 'httparty', :group => :development
#application_controller
def request_ip
if Rails.env.development?
response = HTTParty.get('http://api.hostip.info/get_html.php')
ip = response.split("\n")
ip.last.gsub /IP:\s+/, ''
else
request.remote_ip
end
end
#controller
ip = request_ip
response = Geocoder.search(ip)
( code part with hostip.info from geo_magic gem, and based on the other answer to this question. )
now you can do something like response.first.state
This is an updated answer for geocoder 1.2.9 to provide a hardcoded IP for development and test environments. Just place this at the bottom of your config/initilizers/geocoder.rb:
if %w(development test).include? Rails.env
module Geocoder
module Request
def geocoder_spoofable_ip_with_localhost_override
ip_candidate = geocoder_spoofable_ip_without_localhost_override
if ip_candidate == '127.0.0.1'
'1.2.3.4'
else
ip_candidate
end
end
alias_method_chain :geocoder_spoofable_ip, :localhost_override
end
end
end
you may also do this
request.safe_location