I am learning AWS in ruby, I have the following code in my controller
sqs = WebService.sqs_client
recieved_message = sqs.receive_message({
queue_url: ENV["SQS_URL"], # required
attribute_names: ["Policy"], # accepts Policy, VisibilityTimeout, MaximumMessageSize, MessageRetentionPeriod, ApproximateNumberOfMessages, ApproximateNumberOfMessagesNotVisible, CreatedTimestamp, LastModifiedTimestamp, QueueArn, ApproximateNumberOfMessagesDelayed, DelaySeconds, ReceiveMessageWaitTimeSeconds, RedrivePolicy
message_attribute_names: ["MessageAttributeName"],
max_number_of_messages: 1,
visibility_timeout: 1,
wait_time_seconds: 1,
})
if recieved_message.size > 0
puts recieved_message[0]
end
puts recieved_message.size
However the output is as follows
Started GET "/employee" for 127.0.0.1 at 2016-08-28 12:43:48 -0500
Processing by PageController#employee as HTML
1
Rendered page/employee.html.erb within layouts/application (2.1ms)
Completed 200 OK in 2020ms (Views: 400.4ms | ActiveRecord: 0.0ms)
I have tried adding .body to the end and various other things all to no avail.
Thanks
I figured it out by studying the example here
I needed to put the following code
puts recieved_message["messages"][0]["body"]
Related
Rails 6 with ActionCable
Rspec 3.10
Capybara 3.36
Users visit edit_inventory_path #inventory and see a collection of Counts.
Clicking on a count triggers an AJAX call to populate a modal with the count _form
Filling out the form and clicking submit triggers:
CountsChannel.broadcast_to(
#inventory,
{
count_id: #count.id,
html_slug: render_to_string(partial: 'counts/count', collection: #inventory.counts.sort_by { |c| [c.sort_by_status, - c.item.name] }),
uncounted: "#{view_context.pluralize(#inventory.counts.uncounted.size, 'item')} uncounted."
}
)
This replaces every count div on the page. The newly submitted count is sorted to the bottom of the page and the button text changes.
My test is expecting that button to change from "Count" to "Edit".
RSpec.describe 'Performing an inventory', type: :system do
...
context 'when submitting a count' do
...
it 'changes the count button text' do
# making sure page is loaded
expect(page).to have_content "Edit #{inventory.name}"
# clicking the button opens a modal.
# AJAX puts the count edit form in the modal before it open
find("div#count_#{Count.first.id} a.count-btn").click
# wait to make sure the modal is open
find('input#count_unopened_boxes_count')
fill_in 'count_unopened_boxes_count', with: 5
click_button('Submit')
Rails.logger.debug 'HEYA just hit the submit button.'
# clicking the button closes and clears the modal
# and AJAXs form data to CountsController#update
# which triggers the ActionCable broadcast
# HERE: find('the button', wait: 5) does nothing
# because the old div is still on the page
# so Capybara finds it right away
# wait is a maximum wait time, not an absolute
count_1_btn_text = find("div#count_#{Count.first.id} a.count-btn").text
Rails.logger.debug 'HEYA found the button.'
Rails.logger.debug 'HEYA hoping ActionCable is complete.'
expect(count_1_btn_text).to eq 'Loose Count'
# some time later, the button text actually changes
end
end
end
I know it's a timing issue when I check out test.log:
...
Started GET "/inventories/1/edit" for 127.0.0.1 at 2021-11-29 12:51:05 -0500
...
Processing by InventoriesController#edit as HTML
Parameters: {"id"=>"1"}
...
Rendering layout layouts/application.haml
Rendering inventories/edit.haml within layouts/application
...
Rendered collection of counts/_count.haml [11 times] (Duration: 53.0ms | Allocations: 26025)
...
Completed 200 OK in 10635ms (Views: 10574.2ms | ActiveRecord: 15.7ms | Allocations: 645565)
...
Started GET "/assets/channels/consumer-ddc23d99c3f3572746769fa1851baebf4ef5d005651f6ac89f0739c1682a80bc.js" for 127.0.0.1 at 2021-11-29 12:51:15 -0500
Started GET "/assets/channels/counts_channel-6e2c07931c38a8f979370ee55ad4ca4783da4a2def12996ad4efe6f213d4fb78.js" for 127.0.0.1 at 2021-11-29 12:51:16 -0500
Started GET "/cable" for 127.0.0.1 at 2021-11-29 12:51:16 -0500
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2021-11-29 12:51:16 -0500
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
[1m[36mUser Load (0.6ms)[0m [1m[34mSELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1[0m
Registered connection (Z2lkOi8vYnVpbGQtcGxhbm5lci9Vc2VyLzE)
...
[1m[36mInventory Load (44.2ms)[0m [1m[34mSELECT "inventories".* FROM "inventories" WHERE "inventories"."id" = 1 LIMIT 1[0m
CountsChannel is transmitting the subscription confirmation
CountsChannel is streaming from counts:Z2lkOi8vYnVpbGQtcGxhbm5lci9JbnZlbnRvcnkvMQ
...
...
Rendered counts/_edit.haml (Duration: 48.7ms | Allocations: 28122)
Rendered counts/edit.js.erb (Duration: 50.3ms | Allocations: 28697)
Completed 200 OK in 66ms (Views: 56.2ms | ActiveRecord: 3.4ms | Allocations: 34258)
HEYA just hit the submit button.
...
Started PATCH "/inventories/1/counts/1" for 127.0.0.1 at 2021-11-29 12:51:17 -0500
Processing by CountsController#update as JS
Parameters: {"count"=>{"loose_count"=>"0", "unopened_boxes_count"=>"5"}, "partial_box"=>"Submit Box Count", "inventory_id"=>"1", "id"=>"1"}
HEYA found the button.
HEYA hoping ActionCable is complete.
... 49 lines later ...
[ActionCable] Broadcasting to counts:Z2lkOi8vYnVpbGQtcGxhbm5lci9JbnZlbnRvcnkvMQ: {:count_id=>1, :html_slug=>"...real long string...", :uncounted=>"11 items uncounted."}
Rendering counts/update.js.erb
CountsChannel transmitting {"count_id"=>1, "html_slug"=>"...really long string... (via streamed from counts:Z2lkOi8vYnVpbGQtcGxhbm5lci9JbnZlbnRvcnkvMQ)
Rendered counts/update.js.erb (Duration: 41.1ms | Allocations: 674)
Completed 200 OK in 344ms (Views: 56.4ms | ActiveRecord: 123.9ms | Allocations: 30670)
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2021-11-29 12:51:18 -0500
CountsChannel stopped streaming from counts:Z2lkOi8vYnVpbGQtcGxhbm5lci9JbnZlbnRvcnkvMQ
I've been taught that doing things like sleep() are bad practices, so what are my options to force Capybara to wait a few seconds?
Just tell Capybara what you expect it to find on the page and maximum time to wait for that to appear. In your question you say that you're expecting the button to change from "Count" to "Edit" but then your code is checking for "Loose Count" so I'm not fully clear on exactly what visible change you're expecting, but assuming the latter you could just do something like
expect(page).to have_css("div#count_#{Count.first.id} a.count-btn", text: 'Loose Count', wait: 10)
Additionally there's no point in doing a find followed by fill_in just to wait for the element to appear because fill_in will already wait for the element to appear, so
find('input#count_unopened_boxes_count')
fill_in 'count_unopened_boxes_count', with: 5
is effectively the same as just doing
fill_in 'count_unopened_boxes_count', with: 5
I have a bunch of logger.debug statements in my Controller. They currently write the place where all the HTTP requests and everything are displayed in real time on my WEBRick server. However,
when I write logger.debug statements in my Model, they are not written to this same location, additionally they are not to be found in log/development which is the environment I have been working in. It is particularly frustrating because I make the call to the following Model function in a controller that has successfully executed logger.debug statements:
def process_payment
uri = URI('https://demo.myvirtualmerchant.com/VirtualMerchant/processxml.do')
the_xml = SchoolApplication.to_xml(params[:credit_card],
params[:expiration],
params[:cvv2_cvc2],
params[:amount],
params[:name])
logger.debug(the_xml)
the_xml = the_xml.to_s
my_hash = {'xmldata' => the_xml}
logger.debug(the_xml)
response = Net::HTTP.post_form(uri, my_hash)
#response_var = response
if response.response == 0
render 'receipt'
else
render 'card_Error'
end
end
the two logger.debug statements in this controller method are written to what I suppose is STDOUT? In any case I see them in the location which displays the following kind of information:
Rendered web_applications/card_Error.html.erb within layouts/application (1.7ms)
Completed 200 OK in 433ms (Views: 13.1ms | ActiveRecord: 0.0ms)
Started GET "/assets/jquery.js?body=1" for 127.0.0.1 at 2014-07-22 11:32:02 -0700
In the above Controller method when I make the call to SchoolApplication.to_xml,
it does not execute the corresponding logger.debug() statements (or maybe it writes them
to a different place? That wouldn't make sense but I am also a n00b, clearly) that are in
to_xml Model method as shown below:
def self.to_xml(number,expiration,cvv,amount, name)
xml = ::Builder::XmlMarkup.new
logger.debug(number)
logger.debug(name)
xml.txn {
xml.ssl_test_mode false
xml.ssl_card_number number
xml.ssl_amount amount
xml.ssl_cvv2cvc2_indicator cvv
xml.ssl_first_name name
xml.ssl_show_form false
xml.ssl_exp_date '25/34'
xml.ssl_track_data
xml.ssl_result_format HTML
xml.ssl_receipt_link_method
xml.ssl_receipt_link_url "#{Rails.root}" + '/receipts/receive'
xml.ssl_receipt_link_text
}
xml
end
N.B. I know that the above to_xml is being successfully called and returned from as the rest of my controller method which calls this model function executes without error.
Here is the output after I go to the route which calls the process_payment controller function:
Started POST "/application/pay" for 127.0.0.1 at 2014-07-22 12:13:40 -0700
Processing by WebApplicationsController#process_payment as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"pJD6Q7qJPXFNaGEczv5kTSKBC5TcG8lqhOuLNjw9UrY=", "web_application"=>{"first_name"=>"bob", "last_name"=>"job", "card_number"=>"41111111111111", "expiration_date"=>"232", "cvv2_cvc2"=>"232"}, "commit"=>"Save Web application"}
<txn><ssl_merchant_id/><ssl_user_id/><ssl_ssl_pin/><ssl_test_mode>false</ssl_test_mode> <ssl_card_number/><ssl_amount/><ssl_cvv2cvc2_indicator/><ssl_first_name/ ><ssl_show_form>false</ssl_show_form><ssl_exp_date>25/34</ssl_exp_date><ssl_track_data/><ssl_result_format>HTML</ssl_result_format><ssl_receipt_link_method/><ssl_receipt_link_url> <ssl_receipt_link_text/></txn><to_s/>
<txn><ssl_merchant_id/><ssl_user_id/><ssl_ssl_pin/><ssl_test_mode>false</ssl_test_mode> <ssl_card_number/><ssl_amount/><ssl_cvv2cvc2_indicator/><ssl_first_name/><ssl_show_form>false</ssl_show_form><ssl_exp_date>25/34</ssl_exp_date><ssl_track_data/><ssl_result_format>HTML</ssl_result_format><ssl_receipt_link_method/>
Rendered web_applications/card_Error.html.erb within layouts/application (3.8ms)
Completed 200 OK in 742ms (Views: 22.6ms | ActiveRecord: 0.0ms)
which is equivalent to what was written in development.log
I'm new to Rails (I use Rails 4.0.0). I want to write user management from scratch, without using popular solutions. So, here is my problem.
I have activate action in UsersController:
# GET /users/activate/:code
def activate
if Activation.activate(params[:code])
redirect_to root_path, notice: t('users.activation.success')
else
redirect_to root_path, alert: t('users.activation.failure')
end
end
Here is activate method in Activation model:
def self.activate(activation_code)
if a = Activation.find_by_code(activation_code)
a.destroy
return true
else
return false
end
end
My problem is that after passing valid code to activate action i'm getting my error message (users.activation.failure), but in fact record with activation code disappears from database. I noticed something strange in logs, when leaving a.destroy uncommented:
Started GET "/users/activate/f6dc4cccea5880d77821f0455ec9adf8" for 127.0.0.1 at 2013-09-25 18:53:54 +0200
...
Redirected to http://localhost:3000/
Completed 302 Found in 37ms (ActiveRecord: 30.5ms)
Started GET "/" for 127.0.0.1 at 2013-09-25 18:53:54 +0200
...
Completed 200 OK in 22ms (Views: 21.1ms | ActiveRecord: 0.0ms)
Started GET "/users/activate/f6dc4cccea5880d77821f0455ec9adf8" for 127.0.0.1 at 2013-09-25 18:53:55 +0200
...
Redirected to http://localhost:3000/
Completed 302 Found in 4ms (ActiveRecord: 0.7ms)
Started GET "/" for 127.0.0.1 at 2013-09-25 18:53:55 +0200
...
Completed 200 OK in 16ms (Views: 15.2ms | ActiveRecord: 0.0ms)
There are two /users/activate/f6dc4cccea5880d77821f0455ec9adf8 requests for one actual request. But when I tried to comment u.destroy it seemed to working just fine (without double request).
My question: what am I doing wrong?
Why do you need a separate model for activation? Just put activation code and activation date into users table.
I think that doing variable assignment instead of evaluating a condition is the problem. This will work:
def self.activate(activation_code)
a = Activation.find_by_code(activation_code)
if a.present?
a.destroy
return true
else
return false
end
end
Okay, here's the deal I can't figure out at the moment.
So, I have this action looking like this:
def get
#page = Page.find_by_title(params[:title])
respond_to do |format|
format.html # get.html.erb
format.js # get.js.coffee
end
end
Which, depending on whether it's an AJAX call or a normal GET request, the renders either get.html.erb or get.js.coffee.
In development, that is, as shown by the following log entry:
Started GET "/pages/medien/get" for 127.0.0.1 at 2011-12-11 18:58:31 +0100
Processing by PagesController#get as JS
Parameters: {"title"=>"medien"}
Rendered pages/_get.html.erb (153.0ms)
Rendered pages/get.js.coffee (1185.0ms)
Completed 200 OK in 1230ms (Views: 1220.0ms | ActiveRecord: 5.0ms)
In production the same request and same code results in a log entry like this:
Started GET "/pages/medien/get/" for 91.11.86.230 at 2011-12-11 18:57:44 +0100
Processing by PagesController#get as JS
Parameters: {"title"=>"medien"}
Read fragment views/mypage/pages/medien/get (0.1ms)
Rendered pages/_get.html.erb (0.8ms)
Rendered pages/get.html.erb (0.9ms)
Completed 200 OK in 2ms (Views: 1.5ms | ActiveRecord: 0.2ms)
I simply don't get why it's even stating that it's processing it as JavaScript but then does not execute the javascript in get.js.coffee without even throwing an error!
I am using the command "reset_session" as per here to avoid Session Fixation.
After running the command I would like to store the new generated session_id in the database but session[:session_id] is not defined.
I wrote a simple test:
class ApplicationController < ActionController::Base
protect_from_forgery
after_filter :after_test
def after_test
RAILS_DEFAULT_LOGGER.debug "Old Session: #{session.inspect}"
reset_session
session[:random_number] = ((rand*1000).to_i)
RAILS_DEFAULT_LOGGER.debug "New Session: #{session.inspect}"
end
end
Result in the log for two conescutives pages load is:
Started GET "/" for 127.0.0.1 at 2011-04-16 11:42:57 +0200
Processing by WelcomeController#index as HTML
Rendered welcome/index.html.erb within layouts/application (1.9ms)
Old Session: {"random_number"=>519, "session_id"=>"d17df62e286f20bd25e2714ee4f58020", "_csrf_token"=>"NkD5ZjG/RYLolfRy0ADmr+h+Sp2TXEOQlc6HhNpyp/g="}
New Session: {:random_number=>172}
Completed 200 OK in 7ms (Views: 6.4ms | ActiveRecord: 0.0ms)
and
Started GET "/" for 127.0.0.1 at 2011-04-16 11:42:58 +0200
Processing by WelcomeController#index as HTML
Rendered welcome/index.html.erb within layouts/application (2.0ms)
Old Session: {"random_number"=>172, "session_id"=>"54f46f520c80044a9f5475af78a05502", "_csrf_token"=>"9skbBEN35jQYRgH9oQVz1D5Hsi/o9l7fm7Qx9XDNETc="}
New Session: {:random_number=>497}
Completed 200 OK in 7ms (Views: 6.4ms | ActiveRecord: 0.0ms)
As you can see the random number (172) is properly passed to the second page but the New Session does not show the new session id.
I think the new session id ("54f46f520c80044a9f5475af78a05502") is generated after the "after_filter" but I don't know how to retrieve it.
Yes, rails has this problem. There is a ticket - https://rails.lighthouseapp.com/projects/8994/tickets/2200-session-support-broken
And as you can see it hasn't been resolved yet.