I'm trying to test REST input into a Rails 3 application. I'm using Firefox add-on called RESTclient. For staters, I'm just trying to PUT (Update) one column in a the database (contact2="Bart").
I get back 200, but the column doesn't get updated in the database and the response shows the column to still contain "Mary2"
Here's a pic:
This is the controller:
# PUT /workorders/1
# PUT /workorders/1.json
def update
#workorder = Workorder.find(params[:id])
respond_to do |format|
if #workorder.update_attributes(params[:workorder])
format.html { redirect_to #workorder, notice: 'Workorder was successfully updated.' }
format.json { render json: #workorder }
else
format.html { render action: "edit" }
format.json { render json: #workorder.errors, status: :unprocessable_entity }
end
end
end
Rails Log:
Started PUT "/workorders/56673.json" for 127.0.0.1 at 2015-12-17 14:40:30 -0700
[1m[35mWostatus Load (0.2ms)[0m SELECT "wostatuses".* FROM "wostatuses" ORDER BY position ASC LIMIT 1
Processing by WorkordersController#update as JSON
Parameters: {"id"=>"56673"}
WARNING: Can't verify CSRF token authenticity
[1m[36mWorkorder Load (0.3ms)[0m [1mSELECT "workorders".* FROM "workorders" WHERE "workorders"."id" = $1 LIMIT 1[0m [["id", "56673"]]
[1m[35m (0.1ms)[0m BEGIN
[1m[36m (0.1ms)[0m [1mCOMMIT[0m
Completed 200 OK in 143ms (Views: 0.8ms | ActiveRecord: 0.5ms)
Is the parameter "contact2" not being sent?
I got it working using Wiztools RESTclient.
I had to use:
Body = application/json; charset=UTF-8
{
"contact2": "Bart"
}
Related
I have my form to save to my Stripe_account table. I recently nested the resources and now the form won't save to my database tables. I have it still working with the Stripe API and working there though.
What in my code is lacking?
User Model:
has_one :stripe_account
Stripe_account Model:
belongs_to :users
Stripe_account controller:
def new
#stripe_account = StripeAccount.new
#user = User.find(params[:user_id])
end
def create
#stripe_account = StripeAccount.new(stripe_account_params)
#user = User.find(params[:user_id])
acct = Stripe::Account.create({
.....
.....
#stripe_account.id = current_user.id
#stripe_account.acct_id = acct.id
respond_to do |format|
# #user = User.find(params[:id])
if #stripe_account.save
# current_user = #user
#user.stripe_account = acct.id
format.html { redirect_to new_bank_account_path, notice: 'Stripe account was successfully created.' }
format.json { render :show, status: :created, location: #stripe_account }
else
format.html { render :new }
format.json { render json: #stripe_account.errors, status: :unprocessable_entity }
end
end
end
View:
<%= form_for ([#user, #stripe_account]) do | f | %>
Routes:
resources :users do
resources :stripe_accounts
end
#added for testing
get 'stripe_' => "stripe_account#create"
get 'stripe_new' => "stripe_account#new"
Here's my routes maybe can help?: https://pastebin.com/RVWd2Qq9
Now even though I don't have the "bankaccount" controller or models set up correctly yet, shouldn't it be at least attempting to go there and saving the stripe_account? Just making sure that's not the issue. But it appears it's failing because a new form reloads.
The API is successfully going through as well and the accounts are appearing within stripe, just not my own database.
What in my programming is wrong?
Update to add cmd response:
Started POST "/users/2/stripe_accounts" for 127.0.0.1 at 2018-11-10 00:11:26 -0500
Processing by StripeAccountsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"nz1234567890iJuFwsm/Z4ylhE6zoGdWN6QCfWtDZTH1sxZu/WCdWMKBGkc4zoZ2dOgk9c8UDwRzgqdxrT/sA==", "stripe_account"=>{"account_type"=>"individual", "business_name"=>"", "business_tax_id"=>"", "first_name"=>"Dill", "last_name"=>"Pickles", "ssn_last_4"=>"1234", "dob_month"=>"3", "dob_day"=>"4", "dob_year"=>"1917", "address_line1"=>"198 berry avenue", "address_city"=>"san fran", "address_state"=>"CA", "address_postal"=>"90213", "tos"=>"1", "id"=>"2"}, "full_account"=>"{:value=>\"true\"}", "button"=>"", "user_id"=>"2"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ /home/bob/.rvm/gems/ruby-2.5.1/gems/activerecord-5.2.1/lib/active_record/log_subscriber.rb:98
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]]
↳ app/controllers/stripe_accounts_controller.rb:49
(0.1ms) begin transaction
↳ app/controllers/stripe_accounts_controller.rb:91
(0.1ms) rollback transaction
↳ app/controllers/stripe_accounts_controller.rb:91
Rendering stripe_accounts/new.html.erb within layouts/application
Rendered stripe_accounts/_account_form.html.erb (9.4ms)
Rendered stripe_accounts/new.html.erb within layouts/application (12.5ms)
Rendered layouts/_navbar.html.erb (1.9ms)
Rendered layouts/_footer.html.erb (0.4ms)
Completed 200 OK in 3202ms (Views: 190.0ms | ActiveRecord: 2.4ms)
Validation failed: User must exist
You can either use optional :true to resolve the error
#stipe_account.rb
belongs_to :user, optional: true
#^ should be singular
OR
Assign the user_id in the create action like so
#stripe_account.user_id = current_user.id #add this line
Update:
undefined method `user_id=' for StripeAccount:0x001234f4c58692ae8 Did
you mean? user="
The error is because you don't have user_id column in stripe_accounts table. Generate a migration that will do the job for you
rails g migration add_user_id_to_stripe_accounts user_id:integer
and do rails db:migrate
I use Rails 5.1 and the "redirect_to #search" inside create action doesn't work.
My SearchesController:
class SearchesController < ApplicationController
def new
#search = Search.new
end
def create
#search = Search.create!(search_params)
redirect_to #search # search_path(#search) doesn't work either
end
def show
#search = Search.find(params[:id])
end
private
def search_params
params.require(:search).permit!
end
end
After creating a new search entry by clicking the submit button it doesn't redirect to show page.
My app/views/searches/new.html.erb:
<div>
<h1>Advanced Search Form</h1>
<%= form_with model: #search do |form| %>
<%= form.text_field :keywords %>
<%= form.select :ort, options_from_collection_for_select(Imagecapturing.cities, :ort, :city_name, prompt: false, include_blank: false) %>
<%= form.submit("Suchen", :id=>"button", :class=>"Test", :name=>"submit") %>
<% end %>
</div>
config/routes.rb:
Rails.application.routes.draw do
root 'imagecapturings#index'
resources :searches
end
Log:
Started POST "/searches" for ::1 at 2018-06-14 17:37:54 +0200
Processing by SearchesController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"B91lIUxZZvanOx1luhhfWBJ9mAO5Np/6Bx4xzPdv2Ygj29bprWk5+wIBP7kMVl5Eoxz0KcyJF5DK8UaVUhQaFQ==", "search"=>{"keywords"=>"", "ort"=>"A-St. Paul"}, "submit"=>"Suchen"}
(0.6ms) BEGIN
SQL (22.8ms) INSERT INTO `searches` (`keywords`, `ort`, `created_at`, `updated_at`) VALUES ('', 'A-St. Paul', '2018-06-14 15:37:58', '2018-06-14 15:37:58')
(11.1ms) COMMIT
Redirected to http://localhost:4000/searches/23
Completed 302 Found in 50ms (ActiveRecord: 34.5ms)
Started GET "/searches/23" for ::1 at 2018-06-14 17:37:58 +0200
Processing by SearchesController#show as JS
Parameters: {"id"=>"23"}
Search Load (0.7ms) SELECT `searches`.* FROM `searches` WHERE `searches`.`id` = 23 LIMIT 1
Rendering searches/show.html.erb within layouts/application
Imagecapturing Load (10.4ms) SELECT `imagecapturing`.* FROM `imagecapturing` WHERE (ort LIKE '%A-St. Paul%') ORDER BY `imagecapturing`.`id` DESC
Rendered searches/show.html.erb within layouts/application (62.5ms)
Rendered layouts/_top_nav.html.erb (6.0ms)
Imagecapturing Load (17.0ms) SELECT distinct(ort) FROM `imagecapturing` ORDER BY `imagecapturing`.`ort` ASC
Rendered searches/_links.html.erb (33.5ms)
Completed 200 OK in 409ms (Views: 340.1ms | ActiveRecord: 28.0ms)
Is in "Processing by SearchesController#show as JS" the "as JS" part the issue?
How can I get the redirect working so that after clicking the submit button it redirects to the show action?
--- UPDATE
With suggestion of user Rockwell I modified the create action to:
def create
#search= Search.create!(search_params)
respond_to do |format|
if #search
format.html {redirect_to #search}
format.json { render :show, status: :created, location: #step }
format.js { redirect_to #search }
else
format.html { render :new }
format.json { render json: #search.errors, status: :unprocessable_entity }
format.js { render :new }
end
end
end
But it still processes "as JS":
Started POST "/searches" for ::1 at 2018-06-14 18:09:18 +0200
Processing by SearchesController#create as JS
Parameters: {"utf8"=>"✓", "authenticity_token"=>"D7l5ibv8hu08Z18VKqa0Y+iqGHfT+SIZTIoM8vHdcpArv8pBWszZ4Jldfcmc6LV/Wct0XaZGqnOBZXurVKaxDQ==", "search"=>{"keywords"=>"", "ort"=>"Cologny"}, "submit"=>"Suchen"}
(0.2ms) BEGIN
SQL (11.8ms) INSERT INTO `searches` (`keywords`, `ort`, `created_at`, `updated_at`) VALUES ('', 'Cologny', '2018-06-14 16:09:18', '2018-06-14 16:09:18')
(17.0ms) COMMIT
Redirected to http://localhost:4000/searches/30
Completed 302 Found in 36ms (ActiveRecord: 29.0ms)
Started GET "/searches/30" for ::1 at 2018-06-14 18:09:19 +0200
Processing by SearchesController#show as JS
Parameters: {"id"=>"30"}
Search Load (0.8ms) SELECT `searches`.* FROM `searches` WHERE `searches`.`id` = 30 LIMIT 1
Rendering searches/show.html.erb within layouts/application
Imagecapturing Load (28.1ms) SELECT `imagecapturing`.* FROM `imagecapturing` WHERE (ort LIKE '%Cologny%') ORDER BY `imagecapturing`.`id` DESC
Rendered searches/show.html.erb within layouts/application (16157.3ms)
Rendered layouts/_top_nav.html.erb (3.6ms)
Imagecapturing Load (27.6ms) SELECT distinct(ort) FROM `imagecapturing` ORDER BY `imagecapturing`.`ort` ASC
Rendered searches/_links.html.erb (39.2ms)
Completed 200 OK in 16404ms (Views: 16314.1ms | ActiveRecord: 56.5ms)
I believe that you are correct, the Processing by SearchesController#show as JS is what is causing your error. If you respond to the format it should solve your issue. I added HTML and JSON here but you wouldn't need to if you know you will never need that, just the js should be fine.
def create
#search = Search.new(search_params)
respond_to do |format|
if #search.save
format.html {redirect_to #search}
format.json { render :show, status: :created, location: #step }
format.js { redirect_to #search }
else
format.html { render :new }
format.json { render json: #search.errors, status: :unprocessable_entity }
format.js { render :new }
end
end
end
If you are sending this as an AJAX you could specify the type that gets sent as well, but I would need to see the JS code for that to give a solution to fix that.
it is working as expected, you can see it on the log, the insert is done and then the redirect too.
but the problem is the format you are asking. it seems like the create is called as js Processing by SearchesController#create as JS (maybe you are doing an ajax request with that format or your form has remote:true). and then the redirect isn't done visually of course. you need to make the create request without js format or don't make the redirect on the controller and create a "create.js" view that does the redirect. but of course it's not the best solution.
if you want to do the redirect, the best way is to change the format of the create request.
I am using carrierwave to accept an image from a Python API. I have the following code:
def create
#person = Person.new(person_params)
respond_to do |format|
if #person.save
format.html { redirect_to #person, notice: 'Person was successfully created.' }
format.json { render :show, status: :created, location: #person }
else
format.html { render :new }
format.json { render json: #person.errors, status: :unprocessable_entity }
end
end
end
def person_params
params.permit(:client_file_name, :name, :picture)
end
I had to take out params.require(:person) because the Python library I am using called requests does not allow you to send files in that form.
According to the server logs, the image is saving:
Started POST "/people" for 127.0.0.1 at 2017-11-19 11:49:19 -0500
Processing by PeopleController#create as */*
Parameters: {"picture"=>#<ActionDispatch::Http::UploadedFile:0x007fe5e8e900b8 #tempfile=#<Tempfile:/var/folders/77/2f_jjrld0dxgq3t8xv6clvph0000gn/T/RackMultipart20171119-13141-1nunpha.png>, #original_filename="Phil.png", #content_type=nil, #headers="Content-Disposition: form-data; name=\"picture\"; filename=\"Phil.png\"\r\n">}
(0.0ms) begin transaction
SQL (0.2ms) INSERT INTO "people" ("picture", "created_at", "updated_at") VALUES (?, ?, ?) [["picture", "Phil.png"], ["created_at", "2017-11-19 16:49:19.776189"], ["updated_at", "2017-11-19 16:49:19.776189"]]
(0.6ms) commit transaction
Redirected to http://localhost:3000/people/8
Completed 302 Found in 15ms (ActiveRecord: 1.5ms)
I am only doing this locally. When I look in the directory where the image should be saved, there is an image there called Phil.png which is what should happen except the image has zero bytes.
When I upload the same image using a form, everything works as expected. How do I fix this?
So I figured it out. Rails requires you to set the content-type to image/png, so adding that to the request solved the problem.
I am using paperclip-5.0.0, and Rails 5.0.2.This is my code in controller
class PawsController < ApplicationController
before_action :set_paw, only: [:show, :edit]
def index
#paws = Paw.all
end
def show
end
def new
#paw = Paw.new
end
def edit
end
def create
#paw = Paw.new(paw_params)
respond_to do |format|
if #paw.save
format.html { redirect_to #paw, notice: 'Paw was successfully created.' }
format.json { render :show, status: :created, location: #paw }
else
format.html { render :new }
format.json { render json: #paw.errors, status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_paw
#paw = Paw.find(params[:id])
end
def paw_params
params.require(:paw).permit(:avatar,:name) if params[:avatar]
end
end
Avatar here is the column for paw which stores images.In model I have added required validations for paperclip and validation for presence of name.
Problem: In rails console I am successfully able to open the image file from my computer and add it to the paw model i.e. #paw.save returns true in console, but in the browser it redirects me to the new_paw_url with two errors.
Name can't be blank. and
Avatar can't be blank.
There are no exceptions or errors thrown in between the process.I have no idea how should I fix this.
ActiveRecord::SchemaMigration Load (0.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by PawsController#create as HTML
Parameters: {"utf8"=>"✓","authenticity_token"=>"zKpb2XFEG4FqX3aVQx9oyyGI9x2NpmF+lmt4eZy/3p3VZr2eWYvHLaEjS5AvisJ6iEbRm61SJkJSuTpMx4c0JA==", "paw"=>{"name"=>"Sheru", "gender"=>"Male", "breed"=>"", "dob"=>"", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x005608576e1f30 #tempfile=#<Tempfile:/tmp/RackMultipart20170323-14343-1o95nqx.jpg>, #original_filename="art.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"paw[avatar]\"; filename=\"art.jpg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Upload"}
(0.1ms) begin transaction
(0.1ms) rollback transaction
(0.1ms) begin transaction
(0.1ms) rollback transaction
Rendering paws/new.html.erb within layouts/application
Rendered paws/_form.html.erb (15.8ms)
Rendered paws/new.html.erb within layouts/application (17.3ms)
Rendered layouts/_navbar.html.erb (0.6ms)
Completed 200 OK in 326ms (Views: 287.5ms | ActiveRecord: 2.0ms)
Feel free to ask for any other code snippets from me.
Your paw_params method is breaking it. Remove the if statement and it should work. The problem you're having is that the params you're recieving through your controller are nested in the params[paw] hash and not the params hash. Your paw_params if statement should be
params.require(:paw).permit(:avatar,:name) if params[:paw][:avatar]
Look at the console of your params hash and you'll see that Rails will nest all params submitted via a form helper within the class name of the object. In this case it's paw.
"paw"=>{"name"=>"Sheru", "gender"=>"Male", "breed"=>"", "dob"=>"", "avatar"=>#<ActionDispatch::Http::UploadedFile:0x005608576e1f30
More obviously:
params[:name] #nil
params[:paw][:name] #"Sheru"
Also, it's not a good practice to add conditionals for strong_paramaters based on the presence of certain attributes. If someone submits a name without an avatar, the name wont be permitted due to strong_parameters but would give the user poor feedback. Instead you should use validations in your Paw model that requires the presence of both the name and avatar.
So I have two models Topic, Client. A Client has_and_belongs_to_many :topics, and a Topic has_and_belongs_to_many :clients.
Basically, what I want to happen is...when someone goes to my Topic#index, depending on how they got there (i.e. either via client/:id/topics or just /topics), I want the behavior of the create & new to be different. i.e. at /topics, it just creates a topic. At client/:id/topics it creates a topic and assigns it to that client.
My routes look like this:
resources :topics
resources :clients do
resources :topics
end
My Topics Controller looks like this:
def new
if params[:client_id]
#client = Client.find(params[:client_id])
#topic = #client.topics.build
else
#topic = Topic.new
end
respond_to do |format|
format.html # new.html.erb
format.json { render json: #topic }
end
end
def create
if params[:client_id]
#client = Client.find(params[:client_id])
#topic = #client.topics.build(params[:topic])
else
#topic = Topic.new(params[:topic])
end
respond_to do |format|
if #topic.save
format.html { redirect_to #topic, notice: 'Topic was successfully created.' }
format.json { render json: #topic, status: :created, location: #topic }
else
format.html { render action: "new" }
format.json { render json: #topic.errors, status: :unprocessable_entity }
end
end
end
My views/topics/_form.html.erb looks like this:
<%= form_for([#client, #topic]) do |f| %>
...
<% end %>
However, when I perform an action from client/:id/topics this is what the logs look like:
Started GET "/clients/1/topics/new" for 127.0.0.1 at 2012-09-10 14:33:06 -0500
Processing by TopicsController#new as HTML
Parameters: {"client_id"=>"1"}
Client Load (0.2ms) SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1 [["id", "1"]]
Rendered topics/_form.html.erb (3.6ms)
Rendered topics/new.html.erb within layouts/application (4.7ms)
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
(0.2ms) SELECT COUNT(*) FROM "roles" INNER JOIN "users_roles" ON "roles"."id" = "users_roles"."role_id" WHERE "users_roles"."user_id" = 1 AND (((roles.name = 'admin') AND (roles.resource_type IS NULL) AND (roles.resource_id IS NULL)))
Rendered layouts/_navigation.html.erb (7.2ms)
Rendered layouts/_messages.html.erb (0.1ms)
Completed 200 OK in 61ms (Views: 57.0ms | ActiveRecord: 0.7ms)
That looks good...everything seems to be in order here. But it is in the POST that things seem to be not working:
Started POST "/clients/1/topics" for 127.0.0.1 at 2012-09-10 14:33:13 -0500
Processing by TopicsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"J172LuZQPv8=", "topic"=>{"name"=>"AMZN"}, "commit"=>"Create Topic", "client_id"=>"1"}
Client Load (0.2ms) SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1 [["id", "1"]]
(0.1ms) begin transaction
SQL (186.2ms) INSERT INTO "topics" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", Mon, 10 Sep 2012 19:33:13 UTC +00:00], ["name", "AMZN"], ["updated_at", Mon, 10 Sep 2012 19:33:13 UTC +00:00]]
(4.6ms) commit transaction
Redirected to http://localhost:3000/topics/4
Completed 302 Found in 198ms (ActiveRecord: 191.1ms)
You will notice there is no assignment of the new topic to the client.
What am I missing?
Thanks!
Edit 1
Added puts debug statements to my create action, and this is the result I got after the POST action was executed - which indicates that is getting the params[:client_id] and not just params[:id]:
Served asset /application.js - 304 Not Modified (1ms)
**************************************************
This is the params[:client_id] => {3}
**************************************************
This is the params[:id] => {}
Started POST "/clients/3/topics" for 127.0.0.1 at 2012-09-10 15:06:31 -0500
Processing by TopicsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"J172LuZQc5NYoiMSzDD3oY9vGmxxCX0OdxcGm4GSPv8=", "topic"=>{"name"=>"TEST2"}, "commit"=>"Create Topic", "client_id"=>"3"}
Client Load (0.2ms) SELECT "clients".* FROM "clients" WHERE "clients"."id" = ? LIMIT 1 [["id", "3"]]
(0.1ms) begin transaction
SQL (0.7ms) INSERT INTO "topics" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", Mon, 10 Sep 2012 20:06:31 UTC +00:00], ["name", "TEST2"], ["updated_at", Mon, 10 Sep 2012 20:06:31 UTC +00:00]]
(3.3ms) commit transaction
Redirected to http://localhost:3000/topics/6
Completed 302 Found in 11ms (ActiveRecord: 4.3ms)
Edit 2:
So I tried something else that seems to work, but I would love to know why the above doesn't work.
If, in my Topic#create I just do this:
#client = Client.find(params[:client_id])
#topic = Topic.new(params[:topic])
#client.topics << #topic
It works fine.
But, again...I would love to know why the .build doesn't for HABTM or in this situation.
I think the issue is in the params[:client_id] it may be params[:id].
Can you put a puts statement in your if else block of create action, and then see which one is showing up when you hit the page(create a topic)
EDIT
You need to include accepts_nested_attributes_for in your model to support dynamic building of nested object attributes.
Refer this.
It seems I have to explicitly call save after the build is done on my #client object.
Otherwise, ActiveRecord won't save the transaction and insert a new record in the join_table.