Stripe will not accept payments, the charge keeps failing. I am getting this error:
Started POST "/charges" for 127.0.0.1 at 2014-06-09 06:30:58 -0700
Processing by ChargesController#create as HTML
Parameters: {"utf8"=>"√", "authenticity_token"=>"9bqk2Q6NEM1ehHDJPgncNQ3gnP0X1hQK6y6ENm3Yb1g=", "c
harge"=>{"contest_id"=>"36", "user_id"=>"", "amount"=>"12", "stripe_card_token"=>""}, "card_number"=
>"4242 4242 4242 4242", "card_code"=>"478", "button"=>""}
Stripe error while creating customer: You passed an empty string for 'card'. We assume empty values
are an attempt to unset a parameter; however 'card' cannot be unset. You should remove 'card' from y
our request or supply a non-empty value
Redirected to http://localhost:3000/
Completed 302 Found in 477ms (ActiveRecord: 0.0ms)
It seems as if it might not be creating the stripe token? What is going on here?
This is my form:
<% content_for :head do %>
<%= tag :meta, :name => "stripe-key", :content => STRIPE_PUBLIC_KEY %>
<% end %>
<%= form_for @charge, :html => { :class => 'form' } do |f| %>
<div class="form-inputs">
<div class="row">
<%= f.hidden_field :contest_id, value: @contest.id %>
<%= f.hidden_field :user_id %>
<%= f.hidden_field :amount %>
<!-- TODO CHANGE THIS ACCORDINGLY -->
<%= f.hidden_field :stripe_card_token %>
<div class="small-12 medium-6 large-2 columns">
<%= f.label "Amount:", class: "text-right" %>
</div>
<div class="small-12 medium-6 large-10 columns" style="margin-bottom: 0.5rem; margin-top: 0.5rem;">
<%= number_to_currency(@charge.amount, :unit => "$") %>
</div>
<% if @charge.stripe_card_token.present? %>
Credit card has been provided.
<% else %>
<div class="small-12 medium-6 large-2 columns">
<%= label_tag :card_number, "Credit Card Number:", class: "text-right" %>
</div>
<div class="small-12 medium-6 large-10 columns">
<%= text_field_tag :card_number %>
</div>
<div class="small-12 medium-6 large-2 columns">
<%= label_tag :card_code, "Security Code on Card (CVV):", class: "text-right" %>
</div>
<div class="small-12 medium-6 large-10 columns end">
<%= text_field_tag :card_code %>
</div>
<div class="small-12 medium-6 large-2 columns">
<%= label_tag :card_month, "Card Expiration:", class: "text-right" %>
</div>
<div class="small-6 medium-3 columns">
<%= select_month nil, {add_month_numbers: true}, {name: nil, id: "card_month"} %>
</div>
<div class="small-6 medium-3 columns">
<%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, id: "card_year"} %>
</div>
<% end %>
<div id="stripe_error">
<noscript>JavaScript is not enabled and is required for this form. First enable it in your web browser settings.</noscript>
</div>
</div>
<div class="row">
<div class="form-actions small-9 small-offset-2 columns">
<%= button_tag :type => "button", :class => "radius" do %>
<%= link_to "Back", @contest, :style => "color: white" %>
<% end %>
<%= f.button :Donate, :class => "radius" %>
</div>
</div>
</div>
<% end %>
<% content_for :js do %>
<%= javascript_include_tag "https://js.stripe.com/v1", "application" %>
<%= javascript_include_tag asset_path("stripe/stripe.js"), "application" %>
<% end %>
This is my charges controller:
class ChargesController < ApplicationController
def new
@contest = Contest.find(params[:id])
@charge = Charge.new(amount: params[:amount])
end
def create
@charge = Charge.new(charges_params)
if @charge.save_with_payment(@charge)
redirect_to root_path, :notice => "Contribution was recorded succesfully!"
else
redirect_to root_path, :notice => "Transaction was not able to be recorded"
end
end
def charges_params
params.require(:charge).permit(:stripe_card_token, :contest_id, :user_id, :amount)
end
end
My Charge Model:
class Charge < ActiveRecord::Base
attr_accessor :stripe_card_token
belongs_to :contest
belongs_to :user
def save_with_payment(charge)
if valid?
Stripe::Charge.create(
:amount => (charge.amount.to_i)*100,
:currency => "usd",
:card => stripe_card_token);
save
end
rescue Stripe::InvalidRequestError => e
logger.error "Stripe error while creating customer: #{e.message}"
errors.add :base, "There was a problem with your credit card."
false
end
end
I encountered the same problem.
my subscription.js.coffee:
jQuery ->
Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'))
subscription.setupForm()
subscription =
setupForm: ->
$('#new_subscription').submit (e) ->
$('input[type=submit]').attr('disabled', true)
subscription.processCard()
return false
processCard: ->
card =
number: $('#card_number').val()
cvc: $('#card_code').val()
expMonth: $('#card_month').val()
expYear: $('#card_year').val()
Stripe.createToken(card, subscription.handleStripeResponse)
handleStripeResponse: (status, response) ->
if status == 200
$('#subscription_stripe_card_token').val(response.id)
$('#new_subscription')[0].submit()
else
$('#stripe_error').text(response.error.message)
$('input[type=submit]').attr('disabled', false)
false
As you can see when user pushes submit button the function $('#new_subscription').submit (e) is raised. There is almost all of the stripe magic in the submit function.
In my case sometimes the submit function is not raised therefore empty stripe_card_toke parameter is sent to your server.
The strange behavior is caused by Rails turbolinks facilities.
I solved it in such way:
gem 'jquery-turbolinks' //= require jquery.turbolinks//= require jquery //= require jquery.turbolinks //= require jquery_ujs //= require turbolinks //= require bootstrap //= require jquery_nested_form //= require_tree .
Unrelated to stripe_card_token being blank, your server is currently in PCI scope because it's receiving the card number and CVV code. This is probably not what you're intending if you're using Stripe.
From the Stripe Getting Started docs:
Note how input fields representing sensitive card data (number, CVC, expiration month and year) do not have a "name" attribute. This prevents them from hitting your server when the form is submitted.
Rails tag helpers generate a name attribute by default. That's not desirable in this case.
You can override this behavior by passing nil for both name and value, and defining an identifier of some kind:
<%= text_field_tag nil, nil, 'data-stripe' => 'card_number' %>
Here I've used Stripe's currently-recommended data-stripe, but you can just as well use the id attribute (as their older tutorials recommended).
Getting back to your original question, the problem is in your Charge model, where you're overriding Active Record and masking the data in the database:
class Charge < ActiveRecord::Base
attr_accessor :stripe_card_token # Don't do this!
attr_accessor should never be used on database columns. Active Record provides its own accessors in order to pull that data from the database; by declaring an accessor here, you're replacing Active Record's functionality with Ruby's base functionality:
irb(main):001:0> Charge.first
Charge Load (0.3ms) SELECT "charges".* FROM "charges" ORDER BY "charges"."id" ASC LIMIT 1
=> #<Charge id: 1, stripe_card_token: "0xdeadbeef", created_at: "2014-06-11 14:27:40", updated_at: "2014-06-11 14:27:40">
irb(main):002:0> c.stripe_card_token
=> nil
That being said, the Railscast you started from is nearly three years old, violates best practices all over the place, and uses a long-outdated API endpoint. Once you correct your model, you're still better off starting your form and JavaScript over using Stripe's current tutorial and documentation.
Most likely it looks like stripe_card_token is blank as its
:card => stripe_card_token
try and change that to
:card => charge.stripe_card_token
After upgrading to macOS Golden Gate 27.0.1, my Jekyll-based website stopped working because Bundler cannot find several required gems.
ruby 4.0.9 (2026-10-23 revision 3e93b23afc) +PRISM [arm64-darwin27]
Bundler version 4.0.11
Running bundle list reports:
Could not find eventmachine-1.2.7, http_parser.rb-0.8.1,
bigdecimal-4.1.2 in locally installed gems.
Running bundle install fails when attempting to build native extensions. For example, the build of bigdecimal produces the following error:
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
current directory:
/opt/homebrew/lib/ruby/gems/4.0.0/gems/bigdecimal-4.1.2/ext/bigdecimal
/opt/homebrew/opt/ruby/bin/ruby extconf.rb
checking for __builtin_clz()... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers. Check the mkmf.log file for more details.
The compiler failed to generate an executable file.
(RuntimeError)
You have to install development tools first.
The build log is located at:
/opt/homebrew/lib/ruby/gems/4.0.0/extensions/arm64-darwin-27/4.0.0/bigdecimal-4.1.2/mkmf.log
The relevant excerpt from mkmf.log appears incomplete, so I have not included it here.
I have not installed the full Xcode application, but the Command Line Tools are installed, with a reported version of 27.0.0.0.
Software Update repeatedly attempts to install the Command Line Tools. I deleted the existing installation and allowed Software Update to reinstall it, but the update cycle continues.
What could cause Ruby's native extensions to fail to compile when the Command Line Tools are apparently installed?
How can I determine whether the problem lies with the compiler, SDK configuration, or Ruby installation?
Could the repeated Command Line Tools update attempts be related to the compilation failure, and how can I diagnose this?
I would be grateful for any help or suggestions on how to resolve this.
Did you accept the license after installing the developer tools?
You can accept it with this command:
$ sudo xcodebuild -license
Rails scope returns all(ActiveRecord::Relation) instead of nil.
So that I can use method chain when condition is nil.
class MyClass < ApplicationRecord
scope :my_filter, ->(condition) { where(condition: condition) if condition.present? }
end
MyClass.where(foo: 'foo').my_filter(condition).order(:date)
I want to implement similar functionality in Sequel, but this code doesn't work well because all in Sequel returns an Array. How can I write a functionality in Sequel similar to Rails scope?
class MyClass < Sequel::Model
dataset_module do
def my_filter(condition)
return all if condition.nil?
where(condition: condition)
end
end
end
Since where returns a Dataset I am assuming you would also like "all" to return the same object.
As you have identified all will return an Array; however you can retrieve the Dataset by using either clone or self
So we can just change your implementation to:
class MyClass < Sequel::Model
dataset_module do
def my_filter(condition)
return clone if condition.nil?
where(condition: condition)
end
end
end
Working Example: https://replit.com/@engineersmnky/SequelGemRailsScope#main.rb
Additional Info:
I chose clone because most query methods utilize this method (similar to spawn in ActiveRecord).
Dataset#clone looks like this
def clone(opts = nil || (return self))
c = super(:freeze=>false)
c.opts.merge!(opts)
unless opts.each_key{|o| break if COLUMN_CHANGE_OPTS.include?(o)}
c.clear_columns_cache
end
c.freeze
end
clone's method signature shortcuts execution if no condition is passed and simply returns self.
As stated in the comments
return self used above because clone is called by almost all other query methods, and it is the fastest approach
However the comments do also state
This method should generally not be called directly by user code.
So you could choose to just use return self instead.*
*I implemented both options in my Example above to show their identical functionality plus that method signature is pretty interesting
I've recently moved from C# to Ruby, and I find myself missing the ability to make collapsible, labelled regions of code. It just occurred to me that it ought to be OK to do this sort of thing:
class Example
begin # a group of methods
def method1
..
end
def method2
..
end
end
def method3
..
end
end
...but is it actually OK to do that? Do method1 and method2 end up being the same kind of thing as method3? Or is there some Ruby idiom for doing this that I haven't seen yet?
I know this might be a bit old but I ran into this issue and found a killer solution. If you're using "Rubymine" you can do #regions.
This is where they talk about navigating regions https://www.jetbrains.com/ruby/help/navigating-to-custom-region.html
#region Description
Your code goes here...
#endregion
So with the above in your code you will see the below:
Rubymine code editor - With a sample method using regions un-folded

Rubymine code editor - With a sample method using regions folded

As others have said this doesn't change the method definition.
However, if you want to label groups of methods, why not use Ruby semantics to label them? You could use modules to split your code into chunks that belong together. This is good practice for large classes, even if you don't reuse the modules. When the code grows, it will be easy to split the modules into separate files for better organisation.
class Example
module ExampleGroup
def method1
# ..
end
def method2
# ..
end
end
include ExampleGroup
def method3
# ..
end
end
Adding arbitrary Ruby code in order to please your editor doesn't seem reasonable to me at all. I think you should try to get a decent text editor, one that would be able to configure to use some keyword you put in your comments to enable code folding there, for example:
# region start AAA
some(:code, :here)
# region end AAA
And if you allow me to be sarcastic: you should know that Ruby is lot more expressive, elegant and pretty than C#, and chances are that there isn't any Ruby code ought to be hidden in the first place! ;)
I think it should be OK. I haven't seen it a lot though. Another way you could accomplish the same thing, while using less indentation, is to close and reopen the class, like so:
class Example
def method1
..
end
def method2
..
end
end
# optionally put some other code here
class Example
def method3
..
end
end
I think this is often used so that you can put other code in the middle, such as when there's a constant defined in the first class Example block, which is used to define a constant in the middle code, which is used to define a constant in the second class Example block. That way you never have to refer to a constant before it's defined.
Yes, it is okay to do that (i.e. it doesn't change the semantics of your code).
However this isn't a common pattern and it might be confusing to readers of your code who wouldn't understand what the purpose of the begin ... end block is.
I am looking for a relatively quick way to check whether words are misspelled, either using a gem or API.
I've tried using several gems -- raspell, ffi-aspell, hunspell-ffi, spell_cheker, and spellchecker -- and each has a different error.
I'm pretty new to ruby and hoping for a simple solution (I'm processing a lot of short text files and want to calculate the % of words mis-spelled) that doesn't include building something from scratch.
When trying ffi-aspell, I get the following error:
/Users/ntaylorthompson/.rvm/gems/ruby-1.9.2-p320/gems/ffi-aspell-0.0.3/lib/ffi/aspell/speller.rb:121: [BUG] Segmentation fault
ruby 1.9.2p320 (2012-04-20 revision 35421) [x86_64-darwin11.4.0]
-- control frame ----------
c:0005 p:---- s:0019 b:0019 l:000018 d:000018 CFUNC :speller_check
c:0004 p:0113 s:0013 b:0013 l:000012 d:000012 METHOD /Users/ntaylorthompson/.rvm/gems/ruby-1.9.2-p320/gems/ffi-aspell-0.0.3/lib/ffi/aspell/speller.rb:121
c:0003 p:0049 s:0007 b:0007 l:0005a8 d:0005d0 EVAL ffi-aspell_test.rb:5
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH
c:0001 p:0000 s:0002 b:0002 l:0005a8 d:0005a8 TOP
---------------------------
-- Ruby level backtrace information ----------------------------------------
ffi-aspell_test.rb:5:in `<main>'
/Users/ntaylorthompson/.rvm/gems/ruby-1.9.2-p320/gems/ffi-aspell-0.0.3/lib/ffi/aspell/speller.rb:121:in `correct?'
/Users/ntaylorthompson/.rvm/gems/ruby-1.9.2-p320/gems/ffi-aspell-0.0.3/lib/ffi/aspell/speller.rb:121:in `speller_check'
-- C level backtrace information -------------------------------------------
[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html
Abort trap: 6
I'd appreciate either (1) a suggestion of an alternative approach to those above or (2) a recommendation of which to use of the 5 gems above -- so I can at least spend time debugging the best option.
I made https://github.com/dblock/rubocop-spellcheck.
It checks spelling in Ruby comments, strings, identifiers, Markdown, RDoc, AsciiDoc and plain text. About 20x faster than PySpell.
As jmdeldin said raspell is no longer maintained, ffi-aspell is a fork of it.
I played few minutes with it and it's quite easy to use:
speller.correct?(word)speller.suggestions(word)NOTE: The bigger limitation I've found so far is that the interface of the speller works on words only. If you want to spell check a whole document you'll need to split it in words. This could not be trivial, especially if you have an HTML input...
(It depends on aspell of course so you need to install it using brew install aspell or your preferred package manager)
raspell is no longer maintained, so ffi-aspell is a good option if you have the libaspell headers available.
If you can't get the libraries to work, you can just shell out to the aspell binary. The following method will do just that (unit tests included):
# Returns the percentage of incorrect words per document
#
def spellcheck(filename)
fail "File #{filename} does not exist" unless File.exists?(filename)
words = Float(`wc -w #{filename}`.split.first)
wrong = Float(`cat #{filename} | aspell --list | wc -l`.split.first)
wrong / words
end
if $0 == __FILE__
require 'minitest/autorun'
require 'tempfile'
describe :spellcheck do
def write(str)
@file.write str
@file.read
end
before do
@file = Tempfile.new('document')
end
it 'fails when given a bad path' do
-> { spellcheck('/tmp/does/not/exist') }.must_raise RuntimeError
end
it 'returns 0.0 if there are no misspellings' do
write 'The quick brown fox'
spellcheck(@file.path).must_equal 0.0
end
it 'returns 0.5 if 2/4 words are misspelled' do
write 'jumped over da lacie'
spellcheck(@file.path).must_be_close_to 0.5, 1e-8
end
it 'returns 1.0 if everything is misspelled' do
write 'Da quyck bown foxx jmped oer da lassy dogg'
spellcheck(@file.path).must_equal 1.0, 1e-8
end
after do
@file.close
@file.unlink
end
end
end
spellcheck() assumes you have cat, wc, and aspell on your path, and that the default dictionary is what you want to use. The unit test is for Ruby 1.9 only -- if you're running 1.8, just delete it.
I'm trying to access third party api using TLS 1.2, but getting SSL error event with valid certificates
Ruby Version:
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
Rails Version:
Rails 4.2.5
CODE:
ua = Net::HTTP.new(SERVER, 443)
ua.instance_eval {
@ssl_context = OpenSSL::SSL::SSLContext.new
options = OpenSSL::SSL::OP_NO_SSLv2 | OpenSSL::SSL::OP_NO_SSLv3
if OpenSSL::SSL.const_defined?('OP_NO_COMPRESSION')
options |= OpenSSL::SSL::OP_NO_COMPRESSION
end
@ssl_context.set_params({options: options})
}
# ua.instance_eval { @ssl_context = OpenSSL::SSL::SSLContext.new(:TLSv1_2) }
ua.use_ssl = true
# Checks presence of CA certificate
if File.directory?(RootCA)
ua.ca_path = RootCA
ua.verify_mode = OpenSSL::SSL::VERIFY_PEER
ua.verify_depth = 3
else
puts "Invalid CA certificates directory. Exiting..."
exit
end
ERROR:
OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed
from /home/cp/.rbenv/versions/2.3.0/lib/ruby/2.3.0/net/http.rb:933:in `connect_nonblock'
from /home/cp/.rbenv/versions/2.3.0/lib/ruby/2.3.0/net/http.rb:933:in `connect'
from /home/cp/.rbenv/versions/2.3.0/lib/ruby/2.3.0/net/http.rb:863:in `do_start'
from /home/cp/.rbenv/versions/2.3.0/lib/ruby/2.3.0/net/http.rb:852:in `start'
from /home/cp/.rbenv/versions/2.3.0/lib/ruby/2.3.0/net/http.rb:1398:in `request'
from /home/cp/.rbenv/versions/2.3.0/lib/ruby/2.3.0/net/http.rb:1421:in `send_entity'
from /home/cp/.rbenv/versions/2.3.0/lib/ruby/2.3.0/net/http.rb:1209:in `post'
Issue resolved after building ruby with openssl (https://railsfornovice.wordpress.com/2017/03/02/fix-openssl-cert-error-in-rails/)
I am looking to do scraping of the website https://www.bananatic.com/es/forum/games/
and extract the tags "name", "views" and "replies". I have a big problem to get the non-empty content of the "name" tag. Can you help me? I need to save only the elements that do have text.
This is my code, I have three variables:
Each array should contain only the elements that they have. something but in the names the writings [" "] are saved and I want them not to be saved in my array.

require 'nokogiri'
require 'open-uri'
require 'pp'
require 'csv'
unless File.readable?('data.html')
url = 'https://www.bananatic.com/de/forum/games/'
data = URI.open(url).read
File.open('data.html', 'wb') { |f| f << data }
end
data = File.read('data.html')
document = Nokogiri::HTML(data)
per = document.xpath('//div[@class="replies"]/text()[string-length(normalize-space(.)) > 0]')
.map { |node| node.to_s[/\d+/] }
p per
pir = document.xpath('//div[@class="views"]/text()[string-length(normalize-space(.)) > 0]')
.map { |node| node.to_s[/\w+/] }
p pir
links2 = document.css('.topics ul li div')
res = links2.map do |lk|
name = lk.css('.name p a').inner_text
[name]
end
p res
To fix it I have added a regular expression, however I have failed in the attempt.
I just replace .inner_textwith .to_s[/\w+/], but I don't get it.

👇🏼 Now I have an array with null values and some letters "a" that I don't know where they appear.
This Might Help XPath and CSS.
For your CSS check this out: https://kittygiraudel.github.io/selectors-explained/
The following will get you what you are looking for
document.xpath('//div[@class="topics"]/ul/li//div[@class="name"]/a[@class="js-link avatar"]/text()').map {|node| node.to_s.strip}`.
If you want to understand where your array is coming from take 1 step back and just print out lk.css('.name p a').to_s but the real issue is your selectors are just off.
All that being said looking at the construct of the page you would be better off with something like this:
require 'nokogiri'
require 'open-uri'
url = "https://www.bananatic.com/de/forum/games/"
doc = Nokogiri::HTML(URI.open(url))
# Set a root node set to start from
topics = doc.xpath('//div[@class="topics"]/ul/li')
# loop the set
details = topics.filter_map do |topic|
next unless topic.at_xpath('.//div[@class="name"]') # skip ones without the needed info
# Map details into a Hash
{name: topic.at_xpath('.//div[@class="name"]/a[@class="js-link avatar"]/text()').to_s.strip,
post_year: topic.at_xpath('.//div[@class="name"]/text()[string-length(normalize-space(.)) > 0]').to_s[/\d{4}/],
replies: topic.at_xpath('.//div[@class="replies"]/text()').to_s.strip,
views: topic.at_xpath('.//div[@class="views"]/text()').to_s.strip
}
end
The result of details would be:
[{:name=>"MrCasual2502", :post_year=>"2016", :replies=>"0", :views=>"236"},
{:name=>"MrCasual2502", :post_year=>"2016", :replies=>"0", :views=>"164"},
{:name=>"EdgarAllen", :post_year=>"2022", :replies=>"0", :views=>"1"},
{:name=>"RAMONVC", :post_year=>"2022", :replies=>"0", :views=>"0"},
{:name=>"RAMONVC", :post_year=>"2022", :replies=>"0", :views=>"1"},
{:name=>"tokyobreez", :post_year=>"2021", :replies=>"2", :views=>"18"},
{:name=>"matrix12334", :post_year=>"2022", :replies=>"0", :views=>"2"},
{:name=>"juggalohomie420", :post_year=>"2017", :replies=>"3", :views=>"89"},
{:name=>"Imas86", :post_year=>"2022", :replies=>"2", :views=>"2"},
{:name=>"SmilesImposterr", :post_year=>"2021", :replies=>"1", :views=>"17"},
{:name=>"bebb", :post_year=>"2019", :replies=>"7", :views=>"22"},
{:name=>"IMBANANAZ", :post_year=>"2016", :replies=>"1", :views=>"4"},
{:name=>"IWantSteamKeys", :post_year=>"2021", :replies=>"1", :views=>"4"},
{:name=>"gamormoment", :post_year=>"2021", :replies=>"1", :views=>"47"},
{:name=>"Lovestruck", :post_year=>"2021", :replies=>"3", :views=>"46"},
{:name=>"KillerBotAldwin1", :post_year=>"2021", :replies=>"1", :views=>"95"},
{:name=>"purplevestynstr", :post_year=>"2020", :replies=>"1", :views=>"13"},
{:name=>"Janabanana", :post_year=>"2021", :replies=>"3", :views=>"3"},
{:name=>"apache724", :post_year=>"2017", :replies=>"3", :views=>"33"},
{:name=>"MrsSue66", :post_year=>"2021", :replies=>"1", :views=>"38"}]
I'm running the latest versions of Python and Ruby under Debian Linux version 13.
I make use of text preprocessing both in Python and Ruby, and this is only used for preprocessing text in files that are external to Python and Ruby, and it's never used for preprocessing any code within my Python and Ruby programs themselves.
Because some of these external text files are read by one or more of my Python programs and also one or more of my Ruby programs, I need to use the same templating language for the preprocessing directives that are used in all of these external text files.
Furthermore, I never want to have to shell out to run a preprocessing executable, but rather, I only want to perform the preprocessing via an imported Python package and an imported Ruby package.
Therefore, I need to use a templating package that has versions which are importable into Python programs and also which are importable into Ruby programs.
The only preprocessor that I've found so far which offers a version that can be imported both into Python code and into Ruby code is Mustache (and some of its 3rd-party forks).
But Mustache is limited in that it doesn't offer constructs such as looping and conditional logic. Therefore, I'm looking for alternatives to Mustache which are importable as a Python package and also as a Ruby package.
I've investigated m4, cpp, gpp text preprocessor, Mozilla preprocessor, jinja2, filepp, cheetah, and several others, but so far, none that I've found offer all of the capabilities that I've described here.
Does anyone know of any Mustache alternatives which fit all of my criteria?
It turns out that pycall.rb works for me and doesn't use up too much processing power, so I am now using it in ruby with Cheetah ... and also, of course, I'm using Cheetah directly in the python version of the code. Many thanks to Nick ODell!!!
And it also turns out that erblite is too "lite". Its functionality is a bit limited in comparison to the official ERB, and it also turns out that it handles local variables in python differently from how they are handled in ruby, and this complicates the use of erblite. Perhaps there is a way to work around this, but I decided to not bother spending any more time trying to do so, because of the fact that the pycall.rb/Cheetah set-up is working well for me.
And again, much appreciation to Nick ODell!!!
How can I test with RSpec I'm using rate_limit method on my Rails 8 app?
class SessionsController < ApplicationController
rate_limit to: 10, within: 3.minutes, only: :create
end
In the test environment, the cache is :null_store, and rate_limit counts requests in the cache, so the count never goes up and the limit never kicks in. Switch the test cache to memory
# config/environments/test.rb
config.cache_store = :memory_store
Then a request spec that sends 10 requests and expects the 11th to be blocked
require "rails_helper"
RSpec.describe "Sessions rate limit", type: :request do
before { Rails.cache.clear } # so counts don't carry over between tests
it "blocks the 11th attempt within 3 minutes" do
10.times do
post session_path, params: { email_address: "x@example.com", password: "wrong" }
expect(response).not_to have_http_status(:too_many_requests)
end
post session_path, params: { email_address: "x@example.com", password: "wrong" }
expect(response).to have_http_status(:too_many_requests)
end
end
I am trying to implement a simple local TCP communication between a Ruby server and a C++ library interfaced to Unreal Engine 4.
I have used some sample code for the ruby server, which uses the socket library and instantiates a TCPServer:
require 'socket'
puts "Starting up server..."
# establish the server
## Server established to listen for connections on port 2008
server = TCPServer.new(15300)
# setup to listen and accept connections
while (session = server.accept)
#start new thread conversation
## Here we will establish a new thread for a connection client
Thread.start do
## I want to be sure to output something on the server side
## to show that there has been a connection
puts "log: Connection from #{session.peeraddr[2]} at
#{session.peeraddr[3]}"
puts "log: got input from client"
## lets see what the client has to say by grabbing the input
## then display it. Please note that the session.gets will look
## for an end of line character "\n" before moving forward.
input = session.gets
puts input
## Lets respond with a nice warm welcome message
session.puts "Server: Welcome #{session.peeraddr[2]}\n"
# reply with goodbye
## now lets end the session since all we wanted to do is
## acknowledge the client
puts "log: sending goodbye"
session.puts "Server: Goodbye\n"
end #end thread conversation
end #end loop
This application, if tested with a ruby client, works perfectly fine.
This is the client:
require 'socket'
# establish connection
## We need to tell the client where to connect
## Conveniently it is on localhost at port 15300!
clientSession = TCPSocket.new( "localhost", 15300 )
puts "log: starting connection"
#send a quick message
## Note that this has a carriage return. Remember our server
## uses the method gets() to get input back from the server.
puts "log: saying hello"
clientSession.puts "Client: Hello Server World!\n"
#wait for messages from the server
## You've sent your message, now we need to make sure
## the session isn't closed, spit out any messages the server
## has to say, and check to see if any of those messages
## contain 'Goodbye'. If they do we can close the connection
while !(clientSession.closed?) &&
(serverMessage = clientSession.gets)
## lets output our server messages
puts serverMessage
#if one of the messages contains 'Goodbye' we'll disconnect
## we disconnect by 'closing' the session.
if serverMessage.include?("Goodbye")
puts "log: closing connection"
clientSession.close
end
end #end loop
Server output:
Starting up server...
log: Connection from ::1 at
::1
log: got input from client
Client: Hello Server World!
log: sending goodbye
But when I try to connect to the server using C++11 and the TCP functions in Unreal Engine 4 I do not get any kind of response from the server implemented in ruby (not even "Connection from...").
To understand what was the problem I tried to run some network analysis, starting from the simplest (Window's Resource Monitor), to the most complex (ZenMap). In no case there was a single service running with the selected port open (port 15300). I have double checked every single possible cause for this (e.g. firewall, other security software) but there was no block to the ruby interpreter.
In order to understand why such a simple application is not working I started using Wireshark. It was then that I noticed that there is no local loopback interface, which required me to use RawCap (which manages to capture the local communications and dump them on file). Using it I managed to dump the local communications on my machine during both a run of the ruby client/server pair and Cygwin Socat/Unreal Engine 4. What I found was pretty baffling: there were NO open local TCP sockets on the port for the ruby pair (port 15300), but the TCP ports opened by Unreal Engine 4 were there (along with port 15301, the one I used for the tests).
Update 01
I have changed the code in my Unreal Engine 4 application, as the first version used an included TCPsocket builder which used bind by default instead of connect. Now the code is:
bool UNetworkBlueprintLibrary::NetworkSetup(int32 ServerPort) {
bool res = false;
// Creating a Socket pointer, which will temporary contain our
FSocket* Socket = nullptr;
ISocketSubsystem* SocketSubsystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM);
// Instead of that useless FTcpSocketBuilder I will try to create the socket by hand and then debug it... >:(
if (SocketSubsystem != nullptr) {
// Try to create a stream socket using the system-intependent interface
Socket = SocketSubsystem->CreateSocket(NAME_Stream, TEXT("Server Socket"), false);
if (Socket != nullptr) {
FIPv4Address ServerAddress = FIPv4Address(127, 0, 0, 1);
TSharedRef<FInternetAddr> LocalAddress = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
uint16 castServerPort = (uint16)ServerPort;
// Attach received port and IPAddress to Internet Address pointer
LocalAddress->SetIp(ServerAddress.GetValue());
LocalAddress->SetPort(castServerPort);
bool SocketCreationError = !Socket->Connect(*LocalAddress);
if (SocketCreationError)
{
GLog->Logf(TEXT("Failed to create Server Socket as configured!"));
SocketSubsystem->DestroySocket(Socket);
Socket = nullptr;
}
}
}
if (Socket != nullptr){
UNetworkBlueprintLibrary::ServerSocket = Socket;
res = true;
}
else {
res = false;
}
return res;
}
In order to test whether the code in Unreal Engine 4 is working or not I have used socat under Cygwin:
socat tcp-listen:15300 readline
Once my Unreal Engine 4 application starts I can send data over the socket. I have confirmed this works, removing the possibility that my application developed in Unreal Engine 4 was not communicating through the TCP socket.
Given this positive result I have tried again to use the server code reported on top of this question, removing the lines that wait for a message from the client but the result is the same: the server does not even output the debug lines it should print when there is a connection:
puts "log: Connection from #{session.peeraddr[2]} at #{session.peeraddr[3]}"
Update 02
Back once again!
I have managed to make ruby and Unreal Engine 4 communicate through local TCP sockets. What I needed to make the ruby server work was explicitly providing the local address, like so:
server = TCPServer.new("127.0.0.1", 15300)
However, even if this matter is solved, I am still interested in some of the questions I put the first time.
Update 03
Just one consideration that I made in the last hour.
When I did not provide an explicit server address the server, this command
puts "log: Connection from #{session.peeraddr[2]} at
#{session.peeraddr[3]}"
Returned
log: Connection from ::1 at
::1
Which is indeed correct! ::1 is the IPv6 version of 127.0.0.1, so it looks like that ruby assumes that it has to create an IPv6 socket, instead of an IPv4. Unreal Engine 4 does not provide an IPv6 interface, so this might have been the reason why the application did not work.
Now communications over localhost when dumped, show the following communications over port 15300:
No. Time Source Destination Protocol Length Info
105 7.573433 127.0.0.1 127.0.0.1 TCP 52 9994→15300 [SYN] Seq=0 Win=8192 Len=0 MSS=65495 WS=256 SACK_PERM=1
106 7.573433 127.0.0.1 127.0.0.1 TCP 52 15300→9994 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=65495 WS=256 SACK_PERM=1
107 7.573433 127.0.0.1 127.0.0.1 TCP 40 9994→15300 [ACK] Seq=1 Ack=1 Win=8192 Len=0
108 7.583434 127.0.0.1 127.0.0.1 TCP 66 15300→9994 [PSH, ACK] Seq=1 Ack=1 Win=8192 Len=26
109 7.583434 127.0.0.1 127.0.0.1 TCP 40 9994→15300 [ACK] Seq=1 Ack=27 Win=7936 Len=0
110 7.583434 127.0.0.1 127.0.0.1 TCP 56 15300→9994 [PSH, ACK] Seq=27 Ack=1 Win=8192 Len=16
111 7.583434 127.0.0.1 127.0.0.1 TCP 40 9994→15300 [ACK] Seq=1 Ack=43 Win=7936 Len=0
208 16.450941 127.0.0.1 127.0.0.1 TCP 52 9995→15300 [SYN] Seq=0 Win=8192 Len=0 MSS=65495 WS=256 SACK_PERM=1
209 16.451941 127.0.0.1 127.0.0.1 TCP 52 15300→9995 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=65495 WS=256 SACK_PERM=1
210 16.451941 127.0.0.1 127.0.0.1 TCP 40 9995→15300 [ACK] Seq=1 Ack=1 Win=8192 Len=0
211 16.456941 127.0.0.1 127.0.0.1 TCP 66 15300→9995 [PSH, ACK] Seq=1 Ack=1 Win=8192 Len=26
212 16.456941 127.0.0.1 127.0.0.1 TCP 40 9995→15300 [ACK] Seq=1 Ack=27 Win=7936 Len=0
213 16.456941 127.0.0.1 127.0.0.1 TCP 56 15300→9995 [PSH, ACK] Seq=27 Ack=1 Win=8192 Len=16
214 16.456941 127.0.0.1 127.0.0.1 TCP 40 9995→15300 [ACK] Seq=1 Ack=43 Win=7936 Len=0
When a packages show a LEN of either 26 or 16 means that they are sending either
Server: Welcome 127.0.0.1.
or
Server: Goodbye.
I just wanted to share this information, as it is not really useful for the answer, but shows how IPv6 communications do not pass through the standard localhost virtual adapter.
The questions
What I would like to understand is:
I am calling a method that takes an argument and also uses `**options` to convert remaining key-pair values into a hash. Here's a simpler example method that does the same thing.
def foo(arg1, **options)
[arg1, options]
end
Here's some example calls:
> foo("hello")
=> ["hello", {}]
> foo("hello", :opt1 => "one")
=> ["hello", {:opt1=>"one"}]
> foo("hello", :opt1 => "one", :opt2 => "two")
=> ["hello", {:opt1=>"one", :opt2=>"two"}]
So, we can see it converting the key-values into a hash which is saved as 'options' variable. So far so good.
The problem comes when I try to pass through an actual hash, like so:
> foo("hello", {})
ArgumentError: wrong number of arguments (given 2, expected 1)
I expected this to work like in older versions of ruby, where the standard pattern would be
def foo(arg1, options={})
[arg1, options]
end
Which can be called like
foo("hello", :opt1 => "one", :opt2 => "two")
but can also be called like this:
foo("hello", {})
This is a standard pattern, of passing a hash of options around between methods. In this case, the method i'm calling is one of the built-in rails methods. How can i pass it a hash to use as **options? The hash might be empty.
I found the answer with some experiment: I need to put ** before the hash i'm passing through, eg
> hash = {}
=> {}
> foo("hello", **hash)
=> ["hello", {}]
If I am using DataMapper, and I have two databases, is there any way using migration.rb to copy a table for example table person from database 1 to database 2? (same schema and table values).
Referring this:https://github.com/datamapper/dm-migrations/blob/master/examples/sample_migration.rb
It only tells me how to add/modify/drop tables.
Thanks for help.
I don't think that's the intention of dm-migrations. I believe the easiest way would be something like this:
DataMapper.setup(:default, db1_config)
DataMapper.setup(:new, db2_config)
class Foo
include DataMapper::Resource
property :id, Serial
property :name, String
...
end
DataMapper.finalize
Foo.each do |foo|
DataMapper.repository(:new) do
# It may not let you set the "id" attribute here...
Foo.create(foo.attributes)
end
end
Edit
In hindsight, I'm not sure if you were asking how to to copy table structure as to opposed to table data. This is obviously copying table data.
Is there a way to make this look a little better?
conn.exec 'select attr1, attr2, attr3, attr4, attr5, attr6, attr7 ' +
'from table1, table2, table3, etc, etc, etc, etc, etc, ' +
'where etc etc etc etc etc etc etc etc etc etc etc etc etc'
Like, is there a way to imply concatenation?
This question made me go off a rabbit hole to understand how HEREDOC works. Excuse me if the answer became too long.
The squiggly HEREDOC <<~ is what you are looking for when you want to define a multi-line string with newlines and proper indentation (available since Ruby 2.3):
conn.exec <<~EOS
select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc
where etc etc etc etc etc etc etc etc etc etc etc etc etc
EOS
# -> "select...\nfrom...\nwhere..."
If proper indentation is not a concern, then single and double quotes can span multiple lines in Ruby:
conn.exec "select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc,
where etc etc etc etc etc etc etc etc etc etc etc etc etc"
# -> "select...\n from...\n where..."
If single or double quotes are cumbersome because that would need lots of escaping, then the percent string literal notation % is the most flexible solution:
conn.exec %(select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc
where (ProductLine = 'R' OR ProductLine = "S") AND Country = "...")
# -> "select...\n from...\n where..."
If the aim is to avoid the newlines (which both the squiggly HEREDOC, quotes and the percent string literal will cause), then a line continuation can be used by putting a backslash \ as the last non-whitespace character in a line. This will continue the line and will cause Ruby to concatenate the Strings back to back (watch out for those spaces inside the quoted string):
conn.exec 'select attr1, attr2, attr3, attr4, attr5, attr6, attr7 ' \
'from table1, table2, table3, etc, etc, etc, etc, etc, ' \
'where etc etc etc etc etc etc etc etc etc etc etc etc etc'
# -> "select...from...where..."
If you use Rails, then String.squish will strip the string of leading and trailing space and collapse all consecutive whitespaces (newlines, tabs, and all) into a single space:
conn.exec "select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc,
where etc etc etc etc etc etc etc etc etc etc etc etc etc".squish
# -> "select...attr7 from...etc, where..."
More details:
The Here Document Notation for Strings is a way to designate long blocks of text inline in code. It is started by << followed by a user-defined String (the End of String terminator). All following lines are concatenated until the End of String terminator is found at the very beginning of a line:
puts <<HEREDOC
Text Text Text Text
Bla Bla
HEREDOC
# -> "Text Text Text Text\nBlaBla"
The End of String terminator can be chosen freely, but it is common to use something like "EOS" (End of String) or something that matches the domain of the String such as "SQL".
HEREDOC supports interpolation by default or when the EOS terminator is double quoted:
price = 10
print <<"EOS" # comments can be put here
1.) The price is #{price}.
EOS
# -> "1.) The price is 10."
Interpolation can be disabled if the EOS terminator is single quoted:
print <<'EOS' # Disabled interpolation
3.) The price is #{price}.
EOS
# -> "3.) The price is #{price}."
One important restriction of the <<HEREDOC is that the End of String terminator needs to be at the beginning of the line:
puts <<EOS
def foo
print "foo"
end
EOS
EOS
#-> "....def foo\n......print "foo"\n....end\n..EOS"
To get around this, the <<- syntax was created. It allows the EOS terminator to be indented to make the code look nicer. The lines between the <<- and EOS terminator are still used in their full extend including all indentation:
def printExample
puts <<-EOS # Use <<- to indent End of String terminator
def foo
print "foo"
end
EOS
end
# -> "....def foo\n......print "foo"\n....end"
Since Ruby 2.3, we now have the squiggly HEREDOC <<~ which removes leading whitespace:
puts <<~EOS # Use the squiggly HEREDOC <<~ to remove leading whitespace (since Ruby 2.3!)
def foo
print "foo"
end
EOS
# -> "def foo\n..print "foo"\nend"
Empty lines and lines which only contains tabs and space are ignored by <<~
puts <<~EOS.inspect
Hello
World!
EOS
#-> "Hello\n..World!"
If both tabs and spaces are used, tabs are considered as equal to 8 spaces. If the least-indented line is in the middle of a tab, this tab is not removed.
puts <<~EOS.inspect
<tab>One Tab
<space><space>Two Spaces
EOS
# -> "\tOne Tab\nTwoSpaces"
HEREDOC can do some crazy stuff such as executing commands using backticks:
puts <<`EOC`
echo #{price}
echo #{price * 2}
EOC
HEREDOC String definitions can be "stacked", which means that the first EOS terminator (EOSFOO below) will end the first string and start the second (EOSBAR below):
print <<EOSFOO, <<EOSBAR # you can stack them
I said foo.
EOSFOO
I said bar.
EOSBAR
I don't think anybody would ever use it as such, but the <<EOS is really just a string literal and can be put whereever a string can normally be put:
def func(a,b,c)
puts a
puts b
puts c
end
func(<<THIS, 23, <<THAT)
Here's a line
or two.
THIS
and here's another.
THAT
If you don't have Ruby 2.3, but Rails >= 3.0 then you can use String.strip_heredoc which does the same as <<~
# File activesupport/lib/active_support/core_ext/string/strip.rb, line 22
class String
def strip_heredoc
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "".freeze)
end
end
puts <<-USAGE.strip_heredoc # If no Ruby 2.3, but Rails >= 3.0
This command does such and such.
Supported options are:
-h This message
...
USAGE
If you see errors when Ruby parses your file, then it is most likely that you either have extra leading or trailing spaces with a HEREDOC or extra trailing spaces with a squiggly HEREDOC. For example:
What you see:
database_yml = <<~EOS
production:
database: #{fetch(:user)}
adapter: postgresql
pool: 5
timeout: 5000
EOS
What Ruby tells you:
SyntaxError: .../sample.rb:xx: can't find string "EOS" anywhere before EOF
...sample.rb:xx: syntax error, unexpected end-of-input, expecting `end'
What is at fault:
Spot the extra spaces after the terminating EOS.
See RubyDoc for how to use the percentage string literals. Percentage string literals start with a percentage sign % followed either an opening parenthesis or any non-alphanumeric character. Then you put your string and end the string literal with the associated closing parenthesis symbol or the non-alphanumeric character.
Thus you could use %(...), %[...], %{...} or e.g. %+...+.
No matter which symbol or parentheses (round, square, curly) the result is always the same: Just a string literal.
You simply chose the terminators that are the least likely to be used in the string inside, reducing the need to do escaping. For example, in SPARQL queries {} and () and [] are all used, so it might make sense to use %$...$. In SQL, [] and () are common, thus %{} could be a good pick.
Last, to get the answer to the original question "Is there a way to imply concatenation?" answered: Ruby always implies concatenation if two strings (single and double quoted) are found back to back:
puts "select..." 'from table...' "where..."
# -> "select...from table...where..."
The caveat is that this does not work across line-breaks, because Ruby is interpreting an end of statement and the consequitive line of just strings alone on a line doesn't do anything.
In ruby 2.0 you can now just use %
For example:
SQL = %{
SELECT user, name
FROM users
WHERE users.id = #{var}
LIMIT #{var2}
}
Recently with the new features in Ruby 2.3 the new squiggly HEREDOC will let you write our multiline strings in a nice manner with a minimal change so using this combined with the .squish (if you are using rails) will let you write multiline in a nice way!
in case of just using ruby, you can do a <<~SQL.split.join(" ") which is almost the same
[1] pry(main)> <<~SQL.squish
[1] pry(main)* select attr1, attr2, attr3, attr4, attr5, attr6, attr7
[1] pry(main)* from table1, table2, table3, etc, etc, etc, etc, etc,
[1] pry(main)* where etc etc etc etc etc etc etc etc etc etc etc etc etc
[1] pry(main)* SQL
=> "select attr1, attr2, attr3, attr4, attr5, attr6, attr7 from table1, table2, table3, etc, etc, etc, etc, etc, where etc etc etc etc etc etc etc etc etc etc etc etc etc"
ref: https://infinum.co/the-capsized-eight/multiline-strings-ruby-2-3-0-the-squiggly-heredoc
Like you, I was also looking for a solution which does not include newlines. (While they may be safe in SQL, they're not safe in my case and I have a large block of text to deal with)
This is arguably just as ugly, but you can backslash-escape newlines in a heredoc to omit them from the resulting string:
conn.exec <<~END_OF_INPUT
select attr1, attr2, attr3, attr4, attr5, attr6, attr7 \
from table1, table2, table3, etc, etc, etc, etc, etc, \
where etc etc etc etc etc etc etc etc etc etc etc etc etc
END_OF_INPUT
Note that you cannot due this without interpolation (I.E. <<~'END_OF_INPUT') so be careful. #{expressions} will be evaluated here, whereas they will not in your original code. A. Wilson's answer may be better for that reason.
There are pieces to this answer that helped me get what I needed (easy multi-line concatenation WITHOUT extra whitespace), but since none of the actual answers had it, I'm compiling them here:
str = 'this is a multi-line string'\
' using implicit concatenation'\
' to prevent spare \n\'s'
=> "this is a multi-line string using implicit concatenation to eliminate spare
\\n's"
As a bonus, here's a version using funny HEREDOC syntax (via this link):
p <<END_SQL.gsub(/\s+/, " ").strip
SELECT * FROM users
ORDER BY users.id DESC
END_SQL
# >> "SELECT * FROM users ORDER BY users.id DESC"
The latter would mostly be for situations that required more flexibility in the processing. I personally don't like it, it puts the processing in a weird place w.r.t. the string (i.e., in front of it, but using instance methods that usually come afterward), but it's there. Note that if you are indenting the last END_SQL identifier (which is common, since this is probably inside a function or module), you will need to use the hyphenated syntax (that is, p <<-END_SQL instead of p <<END_SQL). Otherwise, the indenting whitespace causes the identifier to be interpreted as a continuation of the string.
This doesn't save much typing, but it looks nicer than using + signs, to me.
Also (I say in an edit, several years later), if you're using Ruby 2.3+, the operator <<~ is also available, which removes extra indentation from the final string. You should be able to remove the .gsub invocation, in that case (although it might depend on both the starting indentation and your final needs).
EDIT: Adding one more:
p %{
SELECT * FROM users
ORDER BY users.id DESC
}.gsub(/\s+/, " ").strip
# >> "SELECT * FROM users ORDER BY users.id DESC"
<<~TEXT
Hi #{user.name},
Thanks for raising the flag, we're always happy to help you.
Your issue will be resolved within 2 hours.
Please be patient!
Thanks again,
Team #{user.organization.name}
TEXT
Theres a difference in <<-TEXT and <<~TEXT, former retains the spacing inside block and latter doesn't.
There are other options as well. Like concatenation etc. but this one makes more sense in general.
If I am wrong here, let me know how...
You can also use double quotes
x = """
this is
a multiline
string
"""
2.3.3 :012 > x
=> "\nthis is\na multiline\nstring\n"
If needed to remove line breaks "\n" use backslash "\" at the end of each line
Other options:
#multi line string
multiline_string = <<EOM
This is a very long string
that contains interpolation
like #{4 + 5} \n\n
EOM
puts multiline_string
#another option for multiline string
message = <<-EOF
asdfasdfsador #{2+2} this month.
asdfadsfasdfadsfad.
EOF
puts message
To avoid closing the parentheses for each line you can simply use double quotes with a backslash to escape the newline:
"select attr1, attr2, attr3, attr4, attr5, attr6, attr7 \
from table1, table2, table3, etc, etc, etc, etc, etc, \
where etc etc etc etc etc etc etc etc etc etc etc etc etc"
Sometimes is worth to remove new line characters \n like:
conn.exec <<-eos.squish
select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc,
where etc etc etc etc etc etc etc etc etc etc etc etc etc
eos
Yes, if you don't mind the extra newlines being inserted:
conn.exec 'select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc,
where etc etc etc etc etc etc etc etc etc etc etc etc etc'
Alternatively you can use a heredoc:
conn.exec <<-eos
select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc,
where etc etc etc etc etc etc etc etc etc etc etc etc etc
eos
If you do mind extra spaces and newlines, you can use
conn.exec %w{select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc,
where etc etc etc etc etc etc etc etc etc etc etc etc etc} * ' '
(use %W for interpolated strings)
There are multiple syntaxes for multi-line strings as you've already read. My favorite is Perl-style:
conn.exec %q{select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc,
where etc etc etc etc etc etc etc etc etc etc etc etc etc}
The multi-line string starts with %q, followed by a {, [ or (, and then terminated by the corresponding reversed character. %q does not allow interpolation; %Q does so you can write things like this:
conn.exec %Q{select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from #{table_names},
where etc etc etc etc etc etc etc etc etc etc etc etc etc}
I actually have no idea how these kinds of multi-line strings are called so let's just call them Perl multilines.
Note however that whether you use Perl multilines or heredocs as Mark and Peter have suggested, you'll end up with potentially unnecessary whitespaces. Both in my examples and their examples, the "from" and "where" lines contain leading whitespaces because of their indentation in the code. If this whitespace is not desired then you must use concatenated strings as you are doing now.
conn.exec [
"select attr1, attr2, attr3, ...",
"from table1, table2, table3, ...",
"where ..."
].join(' ')
This suggestion has the advantage over here-documents and long strings that auto-indenters can indent each part of the string appropriately. But it comes at an efficiency cost.
conn.exec 'select attr1, attr2, attr3, attr4, attr5, attr6, attr7 ' <<
'from table1, table2, table3, etc, etc, etc, etc, etc, ' <<
'where etc etc etc etc etc etc etc etc etc etc etc etc etc'
<< is the concatenation operator for strings
conn.exec = <<eos
select attr1, attr2, attr3, attr4, attr5, attr6, attr7
from table1, table2, table3, etc, etc, etc, etc, etc,
where etc etc etc etc etc etc etc etc etc etc etc etc etc
eos
I am new to Rails and I'm trying to create a many-to-many connections between a Station model with a Connections table.
I ran
bin/rails g model Station name:string
bin/rails g model Connection from:references to:references
And my create_connections.rb looks as follows:
class CreateConnections < ActiveRecord::Migration[8.1]
def change
create_table :connections do |t|
t.references :from, null: false, foreign_key: { to_table: :stations }
t.references :to, null: false, foreign_key: { to_table: :stations }
t.timestamps
end
end
end
My model connection.rb looks as follows:
class Connection < ApplicationRecord
belongs_to :from, class_name: 'Station'
belongs_to :to, class_name: 'Station'
end
It is trying to look at a tos table for the foreign_key but from what I can tell it shouldn't be given that I've told it where to look for the foreign_key...
Also its weird that I'm not getting the error on the from.
Can you explicitly mention foreign_key?
Something like:
class Connection < ApplicationRecord
belongs_to :from,
class_name: 'Station',
foreign_key: :from_id
belongs_to :to,
class_name: 'Station',
foreign_key: :to_id
end
and something like in Station Model
class Station < ApplicationRecord
has_many :outgoing_connections,
class_name: "Connection",
foreign_key: :from_id
has_many :incoming_connections,
class_name: "Connection",
foreign_key: :to_id
end
The problem was I didn't understand how migrations work. You can't just edit your old migration file and rerun the migraton.
I'm using Ruby 2.1.1 When I run this code:
<CSV.foreach("public/data/original/example_data.csv",headers: true, converters: :numeric) do |info|
I get an error:
No such file or directory @ rb_sysopen
It works if I place example_data.csv in the same directory as shown below, but my boss said it can't be that way he wants all *.csv files in a different directory:
<CSV.foreach("example_data.csv",headers: true, converters: :numeric) do |info|
You should be using Rails.root to generate paths relative to the root of your project:
CSV.foreach(Rails.root.join('public/data/original/example_data.csv'), ...
I had to use a workaround that bypassed File Utilities. Using thoughtbot/paperclip generated a directory called csvcontroller. I placed the csv file in that directory folder.
class Uploader < ActiveRecord::Base
attr_accessible :purchase_name, :item_description, :item_price, :purchase_count,
:merchant_address, :merchant_name, :csvdata
has_attached_file :csvdata, :url => "/csvcontroller/:basename.:extension",
:path => ":rails_root/csvcontroller/:basename.:extension"
#:default_url => "/controllers/original/example_data.csv"
validates_attachment_content_type :csvdata, :content_type => ["text/csv"]
end
Then I placed my parser in that directory to avoid using FileUtils
require 'csv'
@total_cost = 0
#errors out FileUtils.move '/public/data/original/example_data.csv', '/controllers'
#errors out require File.expand_path('../app/public/data/original/', __FILE__)
# errors outCSV.foreach("any_path_name_outside_the_same_directory/example_data.csv",
#headers: true, converters: :numeric) do |info|
CSV.foreach("example_data.csv", headers: true, converters: :numeric) do |info|
a =(info["item price"]).to_f
b = (info["purchase count"]).to_i
@total_cost += a * b
@store = []
customer = []
customer << info["purchaser name"]
@store << info["item description"]
@store << (info["item price"]).to_f
@store << (info["purchase count"]).to_i
@store << info["merchant address"]
@store << info["merchant name"]
puts @customer
puts @store
puts @total_cost
end
It looks ugly but that is what it is. I could not get the FileUtils:: class to work properly. This is a Ruby bug for 2.1.1
I am working with ElasticSearch 8.11. I have a query as follows:
{
query: {
function_score: {
query: {
bool: {
must: [{
multi_match: {
query: 'dave liverpool',
fields: ['name', 'address'],
type: "cross_fields",
minimum_should_match: 2
}
}]
}
}
}
}
}
If I pass a query of dave liverpool into the query, I want to be able to ensure that the query matches at least one token in the address field. So dave would match on name and liverpool would match on address. What I don't want is results where dave and liverpool both occur in the name field. The query is dynamic and I am using the Ruby elasticsearch client. I have used a two-word query here but the query may in reality be longer.
At the moment, the query also returns results where all tokens appear in just one field. I only want results where at least one of the tokens appears in the second field.
The mappings for the two fields are as follows:
"name_comma_analyzed":{"type":"text","analyzer":"comma"}
"address_comma_analyzed":{"type":"text","analyzer":"comma"}
and the analyzer is as follows:
"comma":{"pattern":"(?:,|\\s)+","type":"pattern_replace","replacement":" "}
How can I go about getting the results that I want?
A couple years later, but I was trying to do basically exactly the same thing, and I think something like this might work?
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "dave liverpool",
"fields": [
"name",
"address"
],
"type": "cross_fields",
"operator": "and"
}
}
],
"must_not": [
{
"match": {
"name": "dave liverpool"
}
},
{
"match": {
"address": "dave liverpool"
}
}
]
}
}
}
Basically it doesn't seem like multi-match supports requiring that we have at least one token match on each field, so we can instead just explicitly omit the 2 cases where every token matched on one of the fields.
I have this code in a form
<%= form.label :image, style: "display: block" %>
<%= form.file_field :images, multiple: true %>
and this in the controller
before_action :set_artist, only: %i[ show edit update destroy ]
def post_params
params.require(:post).permit(:title, :content, :images)
end
def create
@artist = Artist.new(artist_params)
respond_to do |format|
if @artist.save
if @artist.images.present?
@artist.images.attach(image)
end
# etc...
def artist_params
params.expect(artist: [:name, :address, :postcode, :mob, :description, :start_date, :end_date, :images])
end
The parameters seem to be passed in as expected
Parameters: {
"authenticity_token" => "[FILTERED]",
"artist" => {
"name" => "C",
"address" => "xxx",
"images" => [
"",
#<ActionDispatch::Http::UploadedFile:0x000071399abad840 @tempfile=#<Tempfile:/tmp/RackMultipart20260922-61310-i1jdmf.jpg>, @content_type="image/jpeg", @original_filename="20260203_0043.jpg", @headers="Content-Disposition: form-data; name=\"artist[images][]\"; filename=\"20260203_0043.jpg\"\r\nContent-Type: image/jpeg\r\n">
]
},
"commit" => "Create Artist"
}
but the images are being stripped out before they are uploaded and artist_params are just
{"name" => "C", "address" => "}
I suspect I need to adjust params.expect. I've tried passing :image, [:images], [] instead of image but get the same result. The dB tables for associations have all been created and seem to be ok. They're just not getting populated. The artist is created, but without the associated images.
There were two separate issues.
The runes I were looking for:
params.expect(artist: [:name, :address, :postcode, :mob, :description, :start_date, :end_date, images: []]
Will log a ticket for the JSON gem issue.
In Clojure it's possible to evalute a form inline and get the result printed. The implementations vary for different editors, but here's how it looks like using Visual Studio Code with Calva:
Is it possible in any editor to do the same (or something similar) with Ruby?
In a sense this is trivially possible in any editor with plugin/scripting capabilities. It's just a question of how much work you're willing to put in.
For example, this blog describes how to do it in Vim. The specific method is not really important, the point is that it's possible because of the features that Vim has:
So it can basically automate what you would do manually: copy some source code, paste that code into the interpreter, run it, capture the result as text, paste it back in the editor.
I suppose this feature is very common for functional languages (at least Elm, Haskell supports this, too) but I don't think it's possible in Ruby. But you can use REPL (eg. IRB or Pry) to get the return value of the statement you typed after pressing enter key.
If there is an IDE Extension that supports this feature I'm very eager to hear about it.
I recently migrated my web application into a desktop application with Electron. I am using Rails 8 to load Vite which loads my frontend with React and TypeScript.
Everything was working well until I introduced Electron, I can log in but I can't update my rooms i.e. updating room status from occupied to vacant or vice versa. I get this error in the console:
Can't verify CSRF token authenticity.
Completed 401 Unauthorized in 40ms (ActiveRecord: 0.0ms (0 queries, 0 cached) | GC: 0.0ms)
I am using session cookies, how can I connect my Ruby on Rails backend with Electron?
Below are my files for Electron:
import { app, BrowserWindow } from "electron";
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
});
// DEV
if (process.env.NODE_ENV === "development") {
win.loadURL("http://localhost:3000");
}
// PROD
else {
win.loadFile("dist/index.html");
}
};
app.whenReady().then(() => {
createWindow();
app.on("activate", () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow();
}
});
});
app.on("window-all-closed", () => {
if (process.platform !== "darwin") {
app.quit();
}
});
I am using Axios and TanStack query from React.
I have a simple rails app where users can login and post updates what i want to do is add a count in each post so if someone visit a post it will get updated suppose if 100 users visited a particular post it should show the count to hundred.
I had seen impressionist but i was thinking to do this without using a gem.
i thought of creating another Modal PostView
class PageView
belongs_to :page
belongs_to :user
end
The best solution for a large project (thousands/millions of users) is punching bag gem , go through the doc for integration : punching_bag
The major problem arises when with each request a new record is created which puts huge load on database. Gem Impressionist fails here. Punching bag too creates records but it has a rake task which comes to rescue :
Schedule a cron job to this rake task once a month/week to decrease (groups the records) the number of records without affecting the count of page views which can be found by simply - @post.hits . Here is the rake task : rake punching_bag:combine[by_hour_after,by_day_after,by_month_after,by_year_after]
Let's think we have a blog with articles. In index page article name ,text and theme of the article will be printed.so we have to introduce a new column to index page of having no of views of an each article.
Do following changes.
app/view/articles/index.html.erb
add to the table .
<th>view</th>
add to the data abstract part start with
<%@articles.each_with_index do |article, index| %> .
<td><%= article.view %></td>
add a new column to articles database as view
or run the code
rails generate migration add_view_to_article view:int
app/controller/articles.controller.rb
def show
@article = Article.find(params[:id])
abc = @article.view += 1
@article.update_attribute "view", abc
end
As suggested by @Deepak, you can add a views field in the model,
def change
add_column :page_views, :count, :integer, default: 0
end
Then, in your controller in show action,
def show
#your show logic
if (user = current_user).present?
current_user.page_views.where(page_id: @page.id).first_or_initialize.increment!(:count)
end
end
This makes sense because whenever the page is visited, counter should be incremented by 1..and your post request is saved..
You can add a views field in the model and increment it on each page view
def change
add_column :page_views, :count, :integer, default: 0
end
and
# app/controllers/pages_controller.rb
def increment
@pageview = PageView.where(user_id: current_user, page_id: params[:id]).first_or_create
@pageview.increment!(:count)
end
And just add a route in pages controller
# routes.rb
resources :pages do
post :increment
end
Since it wasn't mentioned yet, you should also checkout https://github.com/charlotte-ruby/impressionist which makes view tracking very easy and flexible.
This is the data which is saved with each view and could get handy later:
t.string "impressionable_type" # model type: Widget
t.integer "impressionable_id" # model instance ID: @widget.id
t.integer "user_id" # automatically logs @current_user.id
t.string "controller_name" # logs the controller name
t.string "action_name" # logs the action_name
t.string "view_name" # TODO: log individual views (as well as partials and nested partials)
t.string "request_hash" # unique ID per request, in case you want to log multiple impressions and group them
t.string "session_hash" # logs the rails session
t.string "ip_address" # request.remote_ip
t.text "params" # request.params, except action name, controller name and resource id
t.string "referrer" # request.referer
t.string "message" # custom message you can add
So for example you could query something like: "Give me all views for a specific user grouped by Model and Sessions." and stuff like this.
Basically you can add additional field to post, like visit_counter:
class Post
def increase_visit
visit_counter+=1
save!
end
end
Then in posts_controller#show, you can do some increment:
class PostsController
def show
............
@post.increase_visit
end
end
That means, every time you render posts#show view someone actually visited particular post so you should increment number of visits.
In case you need more flexible and advance approach ( to count visits per user, or per days etc ) you can define separate model VisitCounter which would be associated with your Post model.
Regards
ActionView::Template::Error (incompatible character encodings: UTF-8 and ASCII-8BIT): app/controllers/posts_controller.rb:27:in `new'
# GET /posts/new
def new
if params[:post]
@post = Post.new(post_params).dup
if @post.valid?
render :action => "confirm"
else
format.html { render action: 'new' }
format.json { render json: @post.errors, status: :unprocessable_entity }
end
else
@post = Post.new
@document = Document.new
@documents = @post.documents.all
@document = @post.documents.build
end
I don't know why it is happening.
I was upgrading my rails and spree and the error was actually coming from cache
Deleting the cache solved the problem for me
rm -rf tmp/cache
config.encoding = "utf-8" is there in application.rb file.'mysql2' gem instead mysql gem# encoding: utf-8 on top of rake file.Above Rails.application.initialize! line in environment.rb file, add following two lines:
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
solution from here: http://rorguide.blogspot.in/2011/06/incompatible-character-encodings-ascii.html
If above solution not helped then I think you either copy/pasted a part of your Haml template into the file, or you're working with a non-Unicode/non-UTF-8 friendly editor.
If you can recreate that file from the scratch in a UTF-8 friendly editor. There are plenty for any platform and see whether this fixes your problem.
Sometimes you may get this error:
incompatible character encodings: ASCII-8BIT and UTF-8
That typically happens because you are trying to concatenate two strings, and one contains characters that do not map to the character-set of the other string. There are characters in ISO-8859-1 that do not have equivalents in UTF-8, and vice-versa and how to handle string joining with those incompatibilities requires the programmer to step in.
Say we have the following classes: Bakery, Equipment, and Batch. Bakery is composed of Equipment like so:
class Bakery
attr_accessor :equipment
end
Equipment looks like this:
class Equipment
attr_accessor :name, :quantity
end
So to represent a bakery with two ovens we can do this:
ovens = Equipment.new
ovens.quantity = 2
bakery = Bakery.new
bakery.equipment = [ovens]
Now the Batch class represents one batch of baked goods. It is itself composed of a Formula with several Step objects. The Formula class contains the order of steps and timing information so that Batch knows when some equipment needs to be used. (I'm leaving out the Formula and Batch code for brevity. Full code is available here and here.)
My question is how do I use OOD to temporarily transfer ownership of some equipment (say, 1 oven) from bakery to batch. bakery holds an instance of Equipment that represents two ovens. One of those ovens is going to be temporarily occupied by a batch process. Should I create a new instance of Equipment and pass it to the batch while decrementing the quantity of ovens? Or should I not bother with the quantity attribute and simply create one instance of Equipment for each oven in the bakery? In that case I could simply pop the last oven off the bakery.equipment array and push it onto batch.equipment until batch is finished. One business logic requirement is to be able to query future availability of bakery.equipment. So there needs to be some distinction between the current state (i.e. how many ovens are occupied) and future states (i.e. how many ovens will be occupied at 9:00 PM).
I think you incorrectly modeled your data. Your Bakery has not just equipment, but available equipment and occupied equipment. And Batch doesn't own anything, it asks Bakery to temporarily mark some equipment as occupied.
It can be modeled differently depending on your memory/performance/code simplicity requirements.
One example (not performance/memory wise, I suppose, but illustrative) is to have Bakery store available equipment pieces in a list, then pass Bakery to a new Batch instance to mark some slots (or increase usage counter on some items) as busy.
After Batch has marked all equipment in Bakery as busy according to its Formula, Bakery can then be analyzed.
Well, this is just an overall example and it's not very detailed. But then, I don't know the exact problem you are trying to solve ;)
I am trying to run a test with RSpec but it always returns the same error:
DevicesController#update when user is a manager must update any device
Failure/Error: put device_path device_id, params: params, headers: { 'Content-Type': 'application/vnd.api+json' }
TypeError:
no implicit conversion of String into Hash
My function with the request params:
def update_params(device, device_id)
{
data: {
id: device.id,
type: 'device',
attributes: {
device_id: device_id
}
}
}.to_json
end
My test using factories:
context 'when user is a manager' do
let(:user) { create(:manager).account }
let(:firebase_token) { Faker::Crypto.sha1 }
let(:device_id) { physical_device.id }
let(:params) { update_params(physical_device, firebase_token) }
it 'must update any device' do
expect(Device.find(device_id).device_id).to eq(firebase_token)
end
end
The request OS update device:
put device_path device_id, params: params, headers: { 'Content-Type': 'application/vnd.api+json' }
ActionController::TestCase expects the params to be a hash (like the headers).
But the params you pass to this method call
put device_path device_id, params: params, headers: { 'Content-Type': 'application/vnd.api+json' }
are generated by the update_params method and that method calls to_json on the generated hash and therefore returns a JSON string.
Just remove the .to_json from the last line of the update_params method and you should be fine.
Im using prawn to generate a PDF output in a rails app. How do i change the color of the outputted text?
color optiontext "Red color here", color: 'FF0000'
And the result:
With the utmost respect, there is no need to use fill_color as of 2022 because you have to manually set and then unset the color - IMO it's much better to set the color directly via the prawn DSL (domain specific language).
Surely there is a means by which you can pass an ENUM or variable or equivalent instead of passing in a color code?
text "Red color here", color: Color.Red # psuedo-code
I will leave the above as an exercise for the reader.
Have you tried fill_color? Code below should work:
require "rubygems"
require "prawn"
Prawn::Document.generate "hello.pdf" do
fill_color "0000ff"
text_box "Hello World (in blue)", :at => [200,720], :size => 32
end
if you use any 1.x version (it's only a pre-release as of writing) you can also use:
Gem install:
$ gem install prawn --pre
Code:
require "rubygems"
require "prawn"
Prawn::Document.generate "hello.pdf" do
text "Hello World (in blue)", :color => "0000ff", :size => 32
end
Note that you can also set a CMYK color (in this example 100% key black):
fill_color(0,0,0,100)
I am getting this error while doing rake db:migrate of newly cloned app.
'development' database is not configured. Available: ["production"]
So after reading the error, I am doing RAILS_ENV=production rake db:migrate
But this isn't working either.
My database.yml has
production:
adapter: postgresql
encoding: unicode
database: test
pool: 5
username: admin
password: admin
port: 5433
Please suggest.
Your database.yml file shows you have only production environment configured for DB operations. You need to add configuration for development environment as well.
Open your database.yml file and add a configuration for development environment.
Something like the following should suffice (contents in square brackets are to be replaced with your actual values):
development:
adapter:[your adapter]
encoding: [your encoding]
database: [your database for development]
pool: [your pool]
username: [your database server username]
password: [your database server password]
port: [the port you're connecting on]
Remember to indent your yaml code appropriately.
Add
development:
adapter: postgresql
encoding: unicode
database: test
pool: 5
username: admin
password: admin
port: 5433
host: localhost
to database.yml file.
Also, if you test your application, you'll need test environment as well.
I have .csv file with the header row as
VM,Mac Address,Type,"IP Address"
With the following code I can print the value of VM but not IP Address. If remove the "" surrounding IP Address it works.
CSV.foreach(vcenter_vnetwork_file, headers: true, :quote_char => "\x00") do |row|
puts row['VM']
puts row['IP Address']
end
I tried using puts row['\"IP Address\"'] but this did not work. I can programmatically remove those "" from the header row but is there any way to get this working woring without any workaround? I also tried adding :force_quotes => true in the CSV.foreach loop.
Why would you set the :quote_char to be "\x00"? Set it to a quote indeed.
CSV.foreach('/tmp/qqq.csv', headers: true, :quote_char => '"') do |row|
puts row['IP Address']
end
I am using PhantomJS in my Rails app for integration testing of a form that is submitted through AJAX. My test suite runs green the first few times, and then eventually I run into these errors, which appear sporadically:
1) Admin update admin homepage should allow the admin to change a bicycle's listing to approved
Failure/Error: Unable to find matching line from backtrace
ActiveRecord::StatementInvalid:
PG::UnableToSend: : ROLLBACK
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:128:in `exec'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:128:in `block in execute'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract_adapter.rb:425:in `block in log'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activesupport-4.0.0/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract_adapter.rb:420:in `log'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:127:in `execute'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/postgresql/database_statements.rb:218:in `rollback_db_transaction'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/transaction.rb:171:in `perform_rollback'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/transaction.rb:110:in `rollback'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/database_statements.rb:240:in `rollback_transaction'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/fixtures.rb:883:in `block in teardown_fixtures'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/fixtures.rb:882:in `each'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/fixtures.rb:882:in `teardown_fixtures'
# /Users/epicodus/.gem/ruby/2.0.0/gems/activerecord-4.0.0/lib/active_record/fixtures.rb:718:in `after_teardown'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-rails-2.14.0/lib/rspec/rails/adapters.rb:52:in `block (2 levels) in <module:MiniTestLifecycleAdapter>'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/extensions/instance_eval_with_args.rb:16:in `instance_exec'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/extensions/instance_eval_with_args.rb:16:in `instance_eval_with_args'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/example.rb:247:in `instance_eval_with_args'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/hooks.rb:106:in `block (2 levels) in run'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/hooks.rb:108:in `call'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/hooks.rb:108:in `run'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/hooks.rb:446:in `run_hook'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:340:in `run_around_each_hooks'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/example.rb:256:in `with_around_each_hooks'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/example.rb:111:in `run'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:390:in `block in run_examples'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:386:in `map'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:386:in `run_examples'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:371:in `run'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:372:in `block in run'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:372:in `map'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/example_group.rb:372:in `run'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/command_line.rb:28:in `block (2 levels) in run'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/command_line.rb:28:in `map'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/command_line.rb:28:in `block in run'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/reporter.rb:58:in `report'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/command_line.rb:25:in `run'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/runner.rb:80:in `run'
# /Users/epicodus/.gem/ruby/2.0.0/gems/rspec-core-2.14.7/lib/rspec/core/runner.rb:17:in `block in autorun'
2) Admin update admin homepage should text "1 bicycle currently pending"
Failure/Error: Unable to find matching line from backtrace
ActiveRecord::RecordNotFound:
Couldn't find Bicycle with id=515
# ./app/controllers/bicycles_controller.rb:42:in `update'
3) User pages after being redirected to the sign in page, they are redirected back
Failure/Error: Unable to find matching line from backtrace
NoMethodError:
undefined method `cmd_tuples' for nil:NilClass
# ./app/controllers/bicycles_controller.rb:52:in `block (2 levels) in update'
# ./app/controllers/bicycles_controller.rb:43:in `update'
I can get the suite running green again if I run
rake db:drop
rake db:create
rake db:schema:load
rake db:test:prepare
but then the problem persists soon after. The feature works in development without fail. Here's my gemfile:
source 'https://rubygems.org'
gem 'rails', '4.0.0'
gem 'pg'
gem 'sass-rails', '~> 4.0.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
gem 'jbuilder', '~> 1.2'
gem 'paperclip'
gem 'devise'
gem 'bootstrap-sass', :git => 'https://github.com/thomas-mcdonald/bootstrap-sass'
gem 'textacular', "~> 3.0", require: 'textacular/rails'
gem 'will_paginate', '3.0.4'
gem 'will_paginate-bootstrap'
gem 'jquery-ui-rails'
gem "cancan"
gem 'recaptcha-mailhide'
group :production do
gem 'lograge'
gem 'rails_12factor'
end
group :development do
gem 'better_errors'
gem 'binding_of_caller'
gem 'quiet_assets'
end
group :test do
gem 'spork-rails'
gem 'capybara'
gem 'shoulda-matchers'
gem 'launchy'
gem 'poltergeist'
gem 'database_cleaner'
end
group :test, :development do
gem 'rspec-rails'
gem 'pry'
gem 'factory_girl_rails'
end
I know this is an ancient question, but it is one of the few that appears on Google for the error undefined method `cmd_tuples' for nil:NilClass
In my case, in rspec it was being triggered doing something like this:
config.after(:context) do
sql = <<~SQL
SELECT count(*) "count", max(updated_at) "max_updated_at"
from #{table};
SQL
puts ActiveRecord::Base.connection.execute(sql).first.to_h
end
This made no sense, as the same code was run numerous times elsewhere.
For context, I'm using transactional fixtures and the test-prof gem with let_it_be
The error showed up because elsewhere inside a before :each block a thread had experienced a DB error. This appears to have broken the let_it_be connection, leading to this error.
Not a direct answer to the original question maybe, but in rspec with threads performing SQL or ActiveRecord queries that might fail, the root cause is likely somewhere much earlier that where the undefined method `cmd_tuples' for nil:NilClass actually appears.
We are using redis(Elasticache) as our cache store.We are experiencing crashes in our app due to redis connection timeout.We have three app servers and use phusion passenger.At the time of crashes there are about 200 active connections.
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/connection/ruby.rb:55:in `rescue in _read_from_socket'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/connection/ruby.rb:48:in `_read_from_socket'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/connection/ruby.rb:41:in `gets'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/connection/ruby.rb:273:in `read'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:248:in `block in read'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:236:in `io'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:247:in `read'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:112:in `block in call'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:217:in `block (2 levels) in process'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:353:in `ensure_connected'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:207:in `block in process'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:292:in `logging'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:206:in `process'
/home/chillr/deploy/chillr-api/shared/vendor/bundle/ruby/2.2.0/gems/redis-3.2.1/lib/redis/client.rb:112:in `call'
SlOWLOG commands
1) 1) (integer) 6867375
2) (integer) 1486701507
3) (integer) 62008
4) 1) "eval"
2) "for i, name in ipairs(redis.call('KEYS', 'cache:user_transaction_logs:*:9008245678')) do redis.call('DEL', name); end"
3) "0"
2) 1) (integer) 6867374
2) (integer) 1486701507
3) (integer) 61989
4) 1) "KEYS"
2) "cache:user_transaction_logs:*:9008245678"
3) 1) (integer) 6867373
2) (integer) 1486701507
3) (integer) 61026
4) 1) "eval"
2) "for i, name in ipairs(redis.call('KEYS', 'cache:user_transaction_logs:*:8888662136')) do redis.call('DEL', name); end"
3) "0"
4) 1) (integer) 6867372
2) (integer) 1486701507
3) (integer) 61006
4) 1) "KEYS"
2) "cache:user_transaction_logs:*:8888662136"
5) 1) (integer) 6867371
2) (integer) 1486701507
3) (integer) 63070
4) 1) "eval"
We use
No of connections at time of Crash 175..200
GEM redis (3.2.1) redis-rails (5.0.1)
What could be done
Monitor current resource usage for your redis server. Temporally increase your connection timeout redis connection.
Try this check list first
I observe a strange effect using the Docling Serve API.
I'm running Docling as Docker container on macos with Docker Desktop. Depending on the method I use to query the server (with curl and a script from Ruby using HTTParty or Faraday) I end up with different results.
Using curl with the following command...
curl -X 'POST' \
'http://127.0.0.1:5001/v1/convert/file' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'from_formats=pdf' \
-F 'force_ocr=false' \
-F 'image_export_mode=placeholder' \
-F 'files=@<PDF filename>.pdf;type=application/pdf' \
-F 'to_formats=html' \
-F 'to_formats=json' \
I receive a JSON result with both 'to_formats' (in the above case html and json) processed. The HTML and the JSON content is correctly embedded in the 'html_content' and 'json_content' key within the returned JSON.
When I issue the same query using a HTTP library in my Ruby code (HTTParty or Faraday) using the following HTTParty code for example...
require 'httparty'
require 'json'
pdf_path = '<PDF filename>.pdf'
docling_url = 'http://127.0.0.1:5001/v1/convert/file'
body = {
files: File.open(pdf_path),
from_formats: 'pdf',
force_ocr: false,
image_export_mode: 'placeholder',
to_formats: ['html', 'json']
}
response = HTTParty.post(
docling_url,
body: body,
headers: {
'Accept' => 'application/json',
'Content-Type' => 'multipart/form-data'
}
)
if response.success?
puts JSON.pretty_generate(JSON.parse(response.body))
else
puts "#{response.body}"
end
I only receive the default Markdown result returned by the server. Embedded in the 'md_content' key.
Either HTTParty and Faraday should parse the multiple values within the key: value - to_formats: ['html', 'json'] as to_formats=html&to_formats=json which should then be correctly interpreted by the Docling server. In my understanding this is exactly what the two -F entries for 'to_format' in the curl command represent.
The Docling docs describe the required query format as:
Field Name: to_formats
Type: List[OutputFormat]
Description: Output format(s) to convert to. String or list of strings. Allowed values: md, json, yaml, html, html_split_page, text, doctags, vtt, doclang, dclx, chunks, latex. Optional, defaults to Markdown.
Somehow the Docling Serve API cannot process my request in this form and falls back to the default Markdown as return format.
I tried multiple ways of transmitting the value for the 'to_formats' key (e.g. "['html', 'json']") but with no success.
When I issue the call as string only like...
to_formats: 'html'
it works like a charm. But only for one result format type.
Does anyone have an idea how to send such a request to the Docling Serve API and receive multiple result formats within just one API call?
Krid
in addition to Vaultdmns answer I found another easy way to get this going using Faraday. There is a 'flat_encode' option that takes care of handling the duplicate key correctly as well. You need to require the Faraday multipart gem for this to work:
require 'faraday'
require 'faraday/multipart'
require 'json'
pdf_path = '<PDF filename>.pdf'
docling_url = 'http://127.0.0.1:5001/v1/convert/file'
parameters = {
files: Faraday::UploadIO.new(File.open(pdf_path), 'application/pdf'),
to_formats: ["md", "json", "html", "text", "doctags"],
image_export_mode: "placeholder",
do_ocr: false,
force_ocr: false,
table_mode: "fast",
abort_on_error: false
}
conn = Faraday.new(url: docling_url) do |f|
f.request :multipart, flat_encode: true
f.adapter Faraday.default_adapter
end
response = conn.post(docling_url, parameters)
if response.success?
puts JSON.pretty_generate(JSON.parse(response.body))
els
puts response.body
end
This will query the Docling Serve API with all the within 'to_formats' defined result types.
Krid
This is a Ruby/HTTParty issue, not a Docling Serve bug.
curl -F to_formats=html -F to_formats=json sends two separate multipart parts with the same field name. When you pass to_formats: ['html', 'json'] to HTTParty, it can't do that — a Hash only allows one value per key, so it either stringifies the array or sends it as to_formats[]=html&to_formats[]=json. Docling Serve doesn't recognize either of those, so it just falls back to the default.
Fix is to build the multipart body as an array of pairs instead of a Hash, so the key can repeat. Easiest way is to use multipart-post directly (HTTParty uses it internally anyway):
require 'net/http/post/multipart'
require 'json'
require 'uri'
url = URI.parse('http://127.0.0.1:5001/v1/convert/file')
pdf_path = '<PDF filename>.pdf'
params = [
['files', UploadIO.new(File.open(pdf_path), 'application/pdf', File.basename(pdf_path))],
['from_formats', 'pdf'],
['force_ocr', 'false'],
['image_export_mode', 'placeholder'],
['to_formats', 'html'],
['to_formats', 'json']
]
request = Net::HTTP::Post::Multipart.new(url.path, params)
response = Net::HTTP.start(url.host, url.port) { |http| http.request(request) }
result = JSON.parse(response.body)
puts result.keys
That sends to_formats twice, same as curl's repeated -F, and you'll get both html_content and json_content back.
If you want to stick with Faraday, same idea applies — you can't pass a Hash with an array value for multipart, you need to build the parts manually (e.g. with Faraday::Multipart::ParamPart), repeating the key. Not worth the hassle though, multipart-post is simpler for this.
Note: multipart fields are all strings, so force_ocr needs to be 'false', not false.
I just learned about static variables in php. Is there anything like that in ruby?
For example, if we want to create a Student class and for each student object we create, its id number should get incremented automatically.
I thought creating class variable as a static will do.
As mentioned in comments above, @@attr_name changes the value for ALL members of the subclass tree. Use @class_attribute if you want each class to have its own value:
class A
# declared with @ outside of any instance method
@vv = 1
# in order to be accessible from class must set up attr accessor
# ON EVERY CLASS AND SUBCLASS otherwise self.class.vv will NOT work
class << self
attr_accessor :vv
end
# way to address it through accessor in instance methods:
def get_cls_vv
self.class.vv
end
end
class B < A
# declared with @ outside of any instance method
@vv = 2
# in order to be accessible from class must set up attr accessor
# ON EVERY CLASS AND SUBCLASS otherwise self.class.vv will NOT work
class << self
attr_accessor :vv
end
# don't need to redeclare instance methods as they are
# dynamically pointing to underlying class
end
a = A.new
b = B.new
a.get_cls_vv == 1
b.get_cls_vv == 2
Using the accepted answer as the definition of static variable can be dangerous, and it is a common error that I have seen in a lot of Ruby code.
Something like @@foos is shared among ALL subclasses. However, most programmers expect static variables to have scope only within the class where they are defined.
If you are looking for static variables in the sense of most languages, where their scope is only their own class, look at this SO answer
Also this blog post has a nice example of the surprise most programmers will get:
http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/
Class variables are shared between all instances (which is why they're called class variables), so they will do what you want. They're also inherited which sometimes leads to rather confusing behavior, but I don't think that will be a problem here. Here's an example of a class that uses a class variable to count how many instances of it have been created:
class Foo
@@foos = 0
def initialize
@@foos += 1
end
def self.number_of_foos
@@foos
end
end
Foo.new
Foo.new
Foo.number_of_foos #=> 2