ruby handsoap wiredump - ruby-on-rails

How can see the wiredump of a soap using the 'handsoap' library?
I use the on_before_dispatch hook, and right now I am looking at the SoapService variables to see where such a request might be stored.
Hmm.. I should also check out invoke to see which var. is using..
Do you have a quick solution? :D
Thanks

You can dump http-activity by setting the class variable $logger, as in:
Example::FooService.logger = $stdout
This will dump out the http-request and response, nicely formatted. Note that this is not 100% what goes over the wire, since the underlying http-client implementation may add some headers etc. For most uses, ths doesn't matter, but if you're tracing down a bug, you might want to employ wireshark.

I used the hook
def on_before_dispatch
puts ##document
end
and document holds the doc variable.
##document = nil
def on_create_document(doc)
##document = doc
...

On a more abstract (none ruby specific) note, try wireshark. Been using it for wiredumps for all kinds of apps for years.

Related

Disadantages of defining inspect on BigDecimal

I am using the decimal type in Rails for storing currency.
However, I am tired of constantly seeing results like:
nominal_amount: #<BigDecimal:7f919884b648,'0.7E6',9(18)>
When I use the Rails console.
I can fix this by defining inspect as def inspect; to_s; endon BigDecimal, but I am concerned that it could lead to peculiar bugs.
Anyone who can vouch for or warn against this monkey patch?
Ruby Doc suggests to override inspect for user defined classes. It returns a human readable string. No other code should rely on the functionality of inspect. So if you decide, that it is more human-readable - to you - if you change the default behavior it is okay. As long as you don't include it in a gem or other code foreign developers will use.
http://ruby-doc.org/core-2.1.1/Object.html#method-i-inspect
Hmm, if you put it in an initializer and run it in dev mode only... I don't see any risk. There is a chance someone else's code counts on BigDecimal.inspect returning an object string. I would say it's a development only modification.
inspect "Returns debugging information about the value as a string".
See apidock.com/ruby/BigDecimal/inspect
I doubt that overriding debugging output format can break anything. I'm monkey-patching it to to_s as well.

neo4jrb how to reset transaction timeout of an open transaction

Currently using neo4j-community-2.1.7
I understand that the facility has been included in this version.
Have been unable to find any reference to it in the ruby docs.
Would appreciate it very much if I may have some direction on how to reset the timeout using neo4jrb.
Regards
Ross
I am unaware of a way to reset the transaction timeout of an open transaction. Maybe someone more familiar with transactions in the Java API can clarify.
If you want to change the transaction timeout length at boot, that's handled in neo4j-server.properties as described at http://neo4j.com/docs/stable/server-configuration.html.
Within Neo4j-core, if using Neo4j-community or Neo4j-enterprise (and therefore Neo4j Embedded) the code suggests that you can specify a config file by giving a third argument to Neo4j::Session.open, a hash that contains config options. That method, if given :embedded_db as its first arg, will call Neo4j::Embedded#initialize and give that hash as an argument. If you do something like this:
Neo4j::Session.open(:embedded_db, 'path_to_db', properties_file: 'path_and_filename_to_neo4j-server.properties')
It will eventually use that properties file:
db_service.loadPropertiesFromFile(properties_file) if properties_file
This is not demonstrated in any of the specs, unfortunately, but you can see it in the initialize and start methods at https://github.com/neo4jrb/neo4j-core/blob/230d69371ed6bf39297786155ef4f3b1831dac08/lib/neo4j-embedded/embedded_session.rb.
RE: COMMENT INFO
If you're using :server_db, you don't need to include the neo4j-community gem. It isn't loaded, it isn't compatible with Neo4j in Server mode.
That's the first time I've seen the link you provided, good to know that's there. We don't expose a way to do that in Neo4j.rb and won't because it would require some threading magic that we can't support. If you want to do it manually, the best I can tell you is that you can get a current transaction ID this way:
tx = Neo4j::Transaction.new
# do stuff and before your long-running query...
tx.resource_data[:commit].split('/')[-2]
That will return the transaction number that you can use in POST as described in their support doc.
If you'd like help troubleshooting your long-running Cypher query, I'm sure people on SO will help.

Finding options to pass to methods in Rails

How are you supposed to find the different options you can pass to methods in Rails? For instance I want to know the options I can pass to validates. I can't find them nowhere in the documentation.
api dock is useful and it also shows the source code http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates
As you know it's not possible to document hash options in the signature so you must either rely on the quality of the documentation or read the source code.
In this case the docs show some examples that cover pretty much all the default validators. Note that it cannot document all the available since they can be expanded dinamically.
>> ActiveModel::EachValidator.descendants
=> [Paperclip::Validators::AttachmentSizeValidator, ActiveModel::Validations::WithValidator, ActiveModel::Validations::ExclusionValidator, ActiveRecord::Validations::AssociatedValidator, ActiveModel::Validations::ConfirmationValidator, ActiveModel::Validations::PresenceValidator, ActiveModel::Validations::FormatValidator, Paperclip::Validators::AttachmentContentTypeValidator, Paperclip::Validators::AttachmentPresenceValidator, ActiveRecord::Validations::UniquenessValidator, ActiveModel::BlockValidator, ActiveModel::Validations::NumericalityValidator, ActiveModel::Validations::AcceptanceValidator, ActiveModel::Validations::InclusionValidator, ActiveModel::Validations::LengthValidator]
Or:
ActiveModel::EachValidator.descendants.map { |klass| klass.name.split("::").last.sub(/Validator$/, '').underscore }
=> ["attachment_size", "with", "exclusion", "associated", "confirmation", "presence", "format", "attachment_content_type", "attachment_presence", "uniqueness", "block", "numericality", "acceptance", "inclusion", "length"]
The starting point is always the official Rails documentation. For instance, here's the documentation of the validates method.
However, keep in mind that Rails is a constantly evolving framework. Unfortunately, this means that not all methods are fully documented and sometimes you need to dig into the source code directly to understand how a method works.

Rails.cache.fetch, Symbols, & Memcached

I have a rails 2.3.4 app and a line that looks like:
temp = Rails.cache.fetch(:temp_id) { User.find_by_name('Temp').id }
and everything worked fine, until I decided to switch the caching layer to memcached by adding the following to my environment.rb:
config.cache_store = :mem_cache_store
Now the line which used to work fine gives me the following error:
undefined method 'length' for :temp_id:Symbol
/usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/vendor/memcache-client-1.7.4/memcache.rb:645:in 'get_server_for_key'
I understand the error, but I would imagine this common case would have been quickly discovered by a rails test case, so I am wondering if I am doing something wrong. Otherwise, I'm sure I can monkeypatch this issue to convert the symbol to a string.
Thanks
Just use string keys if you can. All the documentation examples use string keys. Although it's not explicitly mentioned as far as I can see, other keys are not supported.
The key arguments are passed directly to the cache implementation, so the different caching flavours may disagree on whether or not they accept anything other than strings.
Because the caches are external with the exception of in-memory cache, I'm not sure that supporting symbols would be useful apart from preventing cases like yours. The key will actually be written to some output somewhere (it's not just internal to your Ruby app), so conceptually the key should be a string.
Edit in reaction to comment: yes, it is of course possible and perfectly reasonable in this case to create a monkey patch to circumvent having to change all calls. What you're suggesting is this (copied into the answer for readability):
class MemCache
def get_server_for_key_with_symbols(key, options = {})
key = key.to_s if key.is_a? Symbol
get_server_for_key_without_symbols(key, options)
end
alias_method_chain :get_server_for_key, :symbols
end
I would also consider just doing a project wide search-and-replace for \.fetch(:\w+) and replace it with \.fetch("$1") (repeat for read and write if necessary). This should probably cover 95% of all cases and a subsequent run of your test suite should catch the rest of the errors.
In general: While the documentation of Rails is pretty good these days, a lot of assumptions are unfortunately still implicit. It's generally a good idea to take a good look at the examples that are given in the documentation, and use the same style. The documented examples are always how the framework was intended to be used.
FWIW, it's canonically Rails.cache.read and Rails.cache.write.

Rails per-request hash?

Is there a way to cache per-request data in Rails? For a given Rails/mongrel request I have the result of a semi-expensive operation that I'd like to access several times later in that request. Is there a hash where I can store and access such data?
It needs to be fairly global and accessible from views, controllers, and libs, like Rails.cache and I18n are.
I'm ok doing some monkey-patching if that's what it takes.
Memcached doesn't work because it'll be shared across requests, which I don't want.
A global variable similarly doesn't work because different requests would share the same data, which isn't what I want.
Instance variables don't work because I want to access the data from inside different classes.
There is also the request_store gem. From the documentation:
Add this line to your application's Gemfile:
gem 'request_store'
and use this code to store and retrieve data (confined to the request):
# Set
RequestStore.store[:foo] = 0
# Get
RequestStore.store[:foo]
Try PerRequestCache. I stole the design from the SQL Query Cache.
Configure it up in config/environment.rb with:
config.middleware.use PerRequestCache
then use it with:
PerRequestCache.fetch(:foo_cache){ some_expensive_foo }
One of the most popular options is to use the request_store gem, which allows you to access a global store that you from any part of your code. It uses Thread.current to store your data, and takes care of cleaning up the data after each request.
RequestStore[:items] = []
Be aware though, since it uses Thread.current, it won't work properly in a multi-threaded environment where you have more than one thread per request.
To circumvent this problem, I have implemented a store that can be shared between threads for the same request. It's called request_store_rails, it's thread-safe, and the usage is very similar:
RequestLocals[:items] = []
Have you considered flash? It uses Session but is automatically cleared.
Memoisation?
According to this railscast it's stored per request.
Global variables are evil. Work out how to cleanly pass the data you want to where you want to use it.
app/models/my_cacher.rb
class MyCacher
def self.result
##result ||= begin
# do expensive stuff
# and cache in ##result
end
end
end
The ||= syntax basically means "do the following if ##result is nil" (i.e. not set to anything yet). Just make sure the last line in the begin/end block is returning the result.
Then in your views/models/whatever you would just reference the function when you need it:
MyCacher.result
This will cache the expensive action for the duration of a request.

Resources