ActionController::ParameterMissing when the parameter is there - ruby-on-rails

So I'm getting this error for whatever reason. It says that the parameter "User" is missing, but I can see it pretty clearly there. Also, I'm not sure why the "user" parameter is listed twice with the second being empty, but I assume that's part of what's causing it.
Started POST "/users" for 127.0.0.1 at 2018-08-30 21:56:48 -0700
Processing by UsersController#create as HTML
Parameters: {"params"=>{"user"=>{"username"=>"fsda", "first_name"=>"fdsa", "last_name"=>"fds", "email"=>"fdsa", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}}, "headers"=>{"Content-Type"=>"application/json"}, "user"=>{}}
Completed 400 Bad Request in 0ms (ActiveRecord: 0.0ms)
ActionController::ParameterMissing (param is missing or the value is empty: user):
app/controllers/users_controller.rb:18:in `user_params'
app/controllers/users_controller.rb:4:in `create'
Here's the piece of code that's making the call from a separate server (React client)
25 ax.post('/users', { |~
26 params: { |~
27 user: this.state |~
28 }, |~
29 headers: { |~
30 "Content-Type": 'application/json' |~
31 } |~
32 })
ax is defined here in a separate file:
1 import axios from 'axios';
2
3 export default axios.create({
4 baseURL: 'http://localhost:3000'
5 })
And here's the Rails controller
3 def create
4 #user.new(user_params)
5 if #user.save
6 json_response(#user, :created)
7 end
8 end
9
10 def show
11 #user = User.find(params[:id])
12 render json: #user
13 end
14
15 private
16
17 def user_params
18 params.require(:user).permit(:username, :email, :first_name, :last_name, :password_digest)
19 end
Sorry about the poor formatting. Copy-pasting from vim is really awkward unless someone knows a better way to do that.
SOLUTION:
Change #user.new(user_params) to #user = User.new(user_params
Change params: { user: {...} } to user: {...}

Related

API Requests not being sent in Production w/Excon Rails 6.0.0

I'm having an issue where my POST request with Excon gem is not being sent out in production, but works perfectly in development. In my logs, it shows Processing ServiceFormsControlller#run_background_check as HTML. I don't know exactly why this is happening...It was working perfectly last week. Now all of a sudden, no requests are being sent out from the production server...It shows the action taking place, but the API endpoint never receives the POST. I added the website to my CORS configuration as a whitelisted domain. That didn't do anything to improve the results.
service_forms_controller.rb
class ServiceFormsController < ApplicationController
#service_form = ServiceForm.find(params[:id])
#service_info = #service_form.info
if #service_info.first_name.present? && #service_info.last_name.present? && #service_info.ssn.present? && #service_info.address.present? && #service_info.email.present?
#report_builder = GoodHire.new
if Rails.env.production?
#report_builder.create_report_for_candidate(#service_info.first_name, #service_info.last_name, #service_info.ssn, #service_info.address, #service_info.email)
# other mandatory fields added to this call
end
redirect_to service_forms_path, notice: "You've submitted the candidate for a background check"
else
redirect_to service_forms_path, notice: "The candidate doesn't have all fields completed"
end
good_hire.rb
class GoodHire
API_KEY_PROD = 'ZZzazzee'
include RestClient
include Excon
def create_report_for_candidate(first_name, last_name, email, ssn, address, city, state, zip, work_histories =[].....,api_key = API_KEY_PROD)
begin
Excon.post("https://api.goodhire.com/v1/Report", body: {
"Candidate": {
"FirstName": "#{first_name}"
....
...
},
"Offer": {
"Products": [
"....ID"
]
},
"RequestOptions": {
"SendPurchaseReceipt": true
}
}.to_json, headers: {"Content-Type" => "application/json", "Authorization" => "ApiKey #{api_key}"})
rescue Excon::Errors => e
puts "RESPONSE ERROR #{e.response}"
end
end
Server Development Log
Started POST "/service_forms/7/run_candidate_bckground_check?id=7" for 127.0.0.1
Processing by ServiceFormsController#run_candidate_background_check as HTML
Parameters: {"authenticity_token" => "zregegegergergergegegege", "id" => "7", "service_form_id"=> "7"}
app/controllers/service_forms_controller.rb: in `run_candidate_background_check'
Redirected to https://127.0.0.1:3000/service_forms
Completed 302 Found in 4359ms
Started GET "/service_forms" for 127.0.0.1
initate_background_check.html.erb
<body>
<%= button_to service_form_run_candidate_background_check(service_form_id: #service_form.id, id: #service_form.id), method: :post, class: 'bttn-simple bttn-sm bttn-primary'do %>
Start Background Check
<% end %>
</body>
API Validations caused API requests to fail

Polling in ES6 and Rails

What I'm doing: I'm trying to make a simple polling mechanism with ES6.
Optimally, it should refresh a partial on index page every 5 seconds.
It doesn't work. Logs write that the template was rendered, but nothing happens in browser.
app/javascript/packs/polls.js.erb:
var sleep = time => new Promise(resolve => setTimeout(resolve, time))
var poll = (promiseFn, time) => promiseFn().then(
sleep(time).then(() => poll(promiseFn, time)))
poll(() => new Promise(() => {
fetch('/shows/refresh_results', {
method: 'GET'
})//.then(response => {
// document.getElementById('top-shows-table-container').innerHTML = ("<%= j render partial: 'shows/top_shows_table' %>");
// })
}), 5000)
app/controllers/application_controller.rb:
class ShowsController < ApplicationController
def index
#shows = Shows::OrderedByAverageReviewsScoreQuery.new.call
end
def refresh_results
#shows = Shows::OrderedByAverageReviewsScoreQuery.new.call
respond_to do |format|
format.js
end
# render :index # this one doesn't work either
end
end
app/views/shows/refresh_results.js.erb:
$('#top-shows-table-container').html("<%= render 'top_shows_table' %>");
CommentPoller.poll();
According to logs, the last file gets called. But nothing happens to page in browser.
Started GET "/shows/refresh_results" for 127.0.0.1 at 2018-12-05 03:06:06 +0300
Processing by ShowsController#refresh_results as */*
Rendering shows/refresh_results.js.erb
Rendered shows/refresh_results.js.erb (0.5ms)
Completed 200 OK in 6ms (Views: 3.6ms | ActiveRecord: 0.0ms)
I also tried inserting .erb code directly into .polls.js, which didn't work either. It is currently commented out. If I do uncomment it, it will produce this error:
ERROR in ./app/javascript/packs/polls.js.erb
Module build failed: Error: rails-erb-loader failed with code: 1
at ChildProcess.<anonymous> (/home/.../projects/leaderboard-challenge/node_modules/rails-erb-loader/index.js:125:16)
at emitTwo (events.js:106:13)
at ChildProcess.emit (events.js:191:7)
at maybeClose (internal/child_process.js:920:16)
at Process.ChildProcess._handle.onexit (internal/child_process.js:230:5)

Ruby on Rails - Action Mailer 400 Bad request

I'm having the following error when I try send a form with Ruby on Rails 4.1 and Action Mailer:
Started POST "/contact_sponsors" for 127.0.0.1 at 2018-05-17 16:22:35 -0300
Processing by ContactSponsorsController#create as JS
Parameters: {"utf8"=>"✓", "contact_sponsor"=>{"company_name"=>"godocu#mailinator.com", "company_cnpj"=>"dahok#mailinator.com", "company_cep"=>"watyhib#mailinator.com", "company_address"=>"dofimocah#mailinator.com", "company_number"=>"duki#mailinator.com", "company_existence"=>"mamopiwir#mailinator.net", "company_sponsor_type"=>"", "responsible_name"=>"qomukuf#mailinator.com", "responsible_email"=>"ryhohiqe#mailinator.net", "additional_infos"=>"Eum sit nesciunt occaecat facere delectus vel aut sint animi pariatur Ut ipsum officia ratione est enim est"}}
HomeConfig Load (4.1ms) SELECT `home_configs`.* FROM `home_configs` ORDER BY `home_configs`.`id` ASC LIMIT 1
(0.2ms) BEGIN
(0.4ms) ROLLBACK
Rendered text template (0.0ms)
Completed 400 Bad Request in 16ms (Views: 0.8ms | ActiveRecord: 4.8ms)
Anyone can help me? I've tried to sort this out in many ways but to no avail. Here is my Controller, Mailer and Model:
class ContactSponsorsController < InheritedResources::Base
def create
#contact_sponsor = ContactSponsor.new
if #contact_sponsor.save
ContactSponsorMailer.delay_for(10.seconds, retry: true).create(#contact_sponsor)
render nothing: true, status: 200
else
render nothing: true, status: 400
end
end
end
class ContactSponsorMailer < ActionMailer::Base
default from: "Facens Lince <no-reply#facens.br>"
def create(contact_sponsor)
#contact_sponsor = contact_sponsor
mail(to: "felipe.marcon#atua.ag", subject: "Contato Através do Site")
end
end
class ContactSponsor < ActiveRecord::Base
validates :company_cnpj, :company_address, :company_number, :company_size, :company_existence, :company_sponsor_type, :responsible_name, :responsible_email, presence: true
end
Thanks.
Look, in the ContactSponsor you have validate those data which must be present but you have not passed any data that means empty that's why
Completed 400 Bad Request
and for this, you need to create a private method for strong parameters look at that below
class ContactSponsorsController < InheritedResources::Base
def create
#contact_sponsor = ContactSponsor.new(contact_sponsor_params)
if #contact_sponsor.save
ContactSponsorMailer.delay_for(10.seconds, retry: true).create(#contact_sponsor)
render nothing: true, status: 200
else
render nothing: true, status: 400
end
end
private
def contact_sponsor_params
params.require(:contact_sponsor).permit(:company_cnpj, :company_address, :company_number, :company_size, :company_existence, :company_sponsor_type, :responsible_name, :responsible_email)
end
end
I think it will work.
#contact_sponsor.save returned false therefore it returns 400.
Check the errors you had with #contact_sponsor.errors.full_messages when it returns false, or use save! to raise an exception (discouraged, use it only for debugging) and see what went wrong.
As per the logs shown and code snippet shared, it seems like the attribute "company_sponsor_type" seems to be blank string and in the model you have the written the presence true of the same attribute and thus it is getting rolled back.
So either remove the validation or send some value in the company_sponsor_type key.

Getting rails error when using Spaceship::Tunes

In a rails app I am running:
54 def itunes_all_apps
55 begin
56 Spaceship::Tunes.login(params[:itunes_username], params[:itunes_password])
57 apps = Spaceship::Tunes::Application.all
58 render json: apps.to_json, status: 200
59 rescue => e
60 render json: {error: e}.to_json, status: 500
61 end
62 end
It returns a status 500 error with no other information every time.
However, if I change this around slightly, for example getting teams (note, from Spaceship, not Spaceship::Tunes) this works fine:
def itunes_all_apps
begin
spaceship = Spaceship.login(params[:itunes_username], params[:itunes_password])
teams = spaceship.teams
render json: teams.to_json, status: 200
rescue => e
render json: {error: e}.to_json, status: 500
end
end
I'm not using any fast file or or config or anything. Just passing in a username and password via an api call and trying to get a response back. I'm new to rails so it may be my implementation of the Spaceship examples provided.
Using spaceship 0.36.1 gem (the latest)
I've pored through the docs to no avail. Grasping for any leads on what I'm doing wrong.
http://www.rubydoc.info/gems/spaceship/Spaceship/Tunes
https://github.com/fastlane/fastlane/blob/master/spaceship/docs/iTunesConnect.md
Someone suggested I run these two commands in irb, which I did, and they worked perfect!
Spaceship::Tunes.login('myAppleId', 'myPassword')
Spaceship::Tunes::Application.all
So it's not an iTunes account problem or credentials problem (because it works in irb), routes problem (because I ran both rails methods above with same route), or params problem (because I ran both rails methods above with same param names).
I really appreciate any suggestions. Thanks.
Edit:
Commenting out begin, rescue, and rending the error, the stack trace is as follows:
2016-10-24T17:47:34.974650+00:00 app[web.1]: Started POST "/api/v1/users/13/itunes_all_apps" for 162.237.102.13 at 2016-10-24 17:47:34 +0000
2016-10-24T17:47:34.977478+00:00 app[web.1]: Processing by Api::V1::UsersController#itunes_all_apps as JSON
2016-10-24T17:47:34.977521+00:00 app[web.1]: Parameters: {"itunes_username"=>"myCorrectUsername", "itunes_password"=>"[FILTERED]", "team_id"=>"myCorrectTeamId", "id"=>"13", "user"=>{}}
2016-10-24T17:47:35.629629+00:00 heroku[router]: at=info method=POST path="/api/v1/users/13/itunes_all_apps" host=myHerokuApp.herokuapp.com request_id=002d906d-354e-4633-8b54-71aa5181e3a7 fwd="161.237.102.13" dyno=web.1 connect=2ms service=657ms status=500 bytes=259
2016-10-24T17:47:35.619597+00:00 app[web.1]: Completed 500 Internal Server Error in 642ms (ActiveRecord: 0.0ms)
2016-10-24T17:47:35.620430+00:00 app[web.1]:
2016-10-24T17:47:35.620432+00:00 app[web.1]: IOError (not opened for reading):
2016-10-24T17:47:35.620434+00:00 app[web.1]:
2016-10-24T17:47:35.620433+00:00 app[web.1]: app/controllers/api/v1/users_controller.rb:58:in `itunes_all_apps'
It seems that Spaceship::Fastlane::Application does not implement as_json method and the default as_json touches some IO object, which cannot be represented as json.
My suggestion would be to create JSON serializer. You could use active_model-serializer, but if you do not want to create a dependency just for one object, then you can create your own serializer.
class SpaceshipApplicationSerializer
attr_reader :spaceship_applications
def initialize(spaceship_applications)
#spaceship_applications = spaceship_applications
end
def as_json(options = {})
spaceship_applications.each_with_object([]) do |spaceship_application, memo|
memo << object_as_json(spaceship_application)
end
end
def object_as_json(object)
attributes.each_with_object({}) do |attribute, memo|
memo[attribute] = object.send(attribute)
end
end
def attributes
[
:apple_id,
:name,
:vendor_id,
:bundle_id,
:last_modified,
:issues_count,
:app_icon_preview_url
]
end
end
# In your controller
def itunes_all_apps
begin
Spaceship::Tunes.login(params[:itunes_username], params[:itunes_password])
apps = Spaceship::Tunes::Application.all
render json: SpaceshipApplicationSerializer.new(apps).to_json, status: 200
rescue => e
render json: {error: e}.to_json, status: 500
end
end
EDIT:
Yes, the classes return an array, but the actual objects in array don't play nicely with json. It's hard to say if the problem is with the library - on one hand Spaceship::Tunes::Application not returning a proper json representation is a missing feature, but if the to_json raises an exception (a method the class responds to) - then I would say that is a bug.
Creating your own serializer to build json representation the way you want it - is a common pattern.

Ruby On Rails authentication issue with http basic(the authentication process is triggered twice for every request)

This is the request I send to the rails controller:
function login(){
$.ajax({
type: 'GET',
url: '/api/myapi/show',
username: 'username',
password: 'password',
contentType: "application/json; charset=utf-8",
success: function(data){
console.log(data);
},
error: function(xhr, ajaxOptions, thrownError) {
console.log(arguments);
}
});
}
login function is used as follows:
<body onload='login();'>
This is the controller:
class Api::MyApi::BaseController < ApplicationController
before_filter :authenticate
attr_reader :user
def authenticate
authenticate_or_request_with_http_basic do |username, password|
#authenticate method checks if user with username and password exists in database
#user = User.authenticate(username, password)
end
end
end
When I send the request, this is what's printed in the terminal:
Started GET "/api/myapi/show" for 127.0.0.1 at 2015-12-15 09:42:22 +0100
Processing by Api::MyApi#show as JSON
Parameters: {"id"=>"show", "test"=>{}}
Filter chain halted as :authenticate rendered or redirected
Completed 401 Unauthorized in 0ms (ActiveRecord: 0.0ms)
Started GET "/api/myapi/show" for 127.0.0.1 at 2015-12-15 09:42:22 +0100
Processing by Api::MyApi#show as JSON
Parameters: {"id"=>"show", "test"=>{}}
User Load (0.1ms) SELECT `users`.* FROM `users` WHERE `users`.`authorized` = 1 AND `users`.`verification_approved` = 1 AND `users`.`login` = 'user_login' LIMIT 1
Location Load (0.1ms) SELECT `locations`.* FROM `locations` WHERE `locations`.`id` = 9999 LIMIT 1
Rendered api/myapi/show.json.rabl (0.5ms)
Completed 200 OK in 8ms (Views: 2.6ms | ActiveRecord: 0.7ms)
As you can see, it tries to authenticate twice and fails the first time. It doesn't even get inside "authenticate_or_request_with_http_basic" because if I write a print statement inside the "authenticate_or_request_with_http_basic", it doesn't get printed the first time(when authentication fails), but does get printed the second time.
Things I tried:
1) When Removing the before_filter completely and just authenticating in the show method, the issue doesn't occur anymore.
2) When keeping/using the before_filter but replacing the authenticate_or_request_with_http_basic with 'true' like this:
def authenticate
true
end
the issue doesn't occur either.
3) The issue doesn't occur when I send a request with python:
import requests
r = requests.get('URL_TO__RoR_Controller', auth=('username', 'password'))
print r.text
UPDATE:
This might be useful info: The request is sent every 10 seconds, and the credentials are sent with every request. Perhaps this has something to do with the issue.
You are sending username and password as params
AFAIK Basic auth works by setting the authorization headers
Use jQuery's beforeSend callback to add an HTTP header with the authentication information: http://api.jquery.com/jQuery.ajax/
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic " + btoa(username + ":" + password));
},
The btoa() method encodes a string in base-64.
In your controller you can check the headers with
request.env["HTTP_AUTHORIZATION"]
Let me know if this works for you.

Resources