I want to convert my XML document to Hash in Ruby/Rails. Actually, the default conversion by Hash.from_xml in Rails works for me except in one case.
I have a list of items contained in <item-list> element, these items can be of different types though. For instance, standard-item and special-item, each of which has different set of child elements.
<item-list>
<standard-item>
<foo>...</foo>
<bar>...</bar>
</standard-item>
<standard-item>
<foo>...</foo>
<bar>...</bar>
</special-item>
<special-item>
<baz>...</baz>
</special-item>
</item-list>
This XML structure can be confusing for Hash.from_xml as it does not know that both standard-item and special-item are both items and should be in the same level. Hence, from the above XML, the hash generated by Hash.from_xml will be:
{ 'item-list' => { 'standard-item' => [ { 'foo' => '...', 'bar' => '...' },
{ 'foo' => '...', 'bar' => '...' } ],
'special-item' => { 'baz' => '...' } }}
But what I want is to have all items as list members, like this:
{ 'item-list' => [ { 'standard-item' => { 'foo' => '...', 'bar' => '...' } },
{ 'standard-item' => { 'foo' => '...', 'bar' => '...' } },
{ 'special-item' => { 'baz' => '...' } } ]
Is it possible to extend/customize from_xml so that it performs to way I want to for this case? If it is not possible, what is the best way to achieve this? Given that this is the only element that contains something that deviates from general XML-to-Hash conversion, it does not seem right to me to implement the whole conversion routine where it might have already been implemented for a thousand times.
Another small note, Hash.to_xml also replaces all dashes with underscores. Is there a way to prevent this replacement?
This is correct behavior.
<a>
<b>one</b>
<b>two</b>
</a>
Think about how this would be converting to a hash, there cannot be two values assigned to the key 'b'. The only solution is to make the value of 'b' a hash containing an array of 'one' and 'two'.
{a => {
b => ['one', 'two']
}}
This is simply how Rails represents XMLs. You will need to check for an array value in the hash, and act accordingly.
Related
We have the following mapping in EF6:
HasRequired(x => x.modulemain).WithMany().HasForeignKey(t => t.moduleid);
HasOptional(t => t.modulerslt).WithMany().HasForeignKey(t => new { t.moduleid, t.trmendrs });
HasOptional(x => x.modulegoal).WithMany().HasForeignKey(t => new { t.moduleid, t.trmgcode });
HasOptional(x => x.modulefase).WithMany().HasForeignKey(t => new { t.moduleid, t.trmfcode });
Breezejs understands this mapping with the combination of the two keys. BUT there is a problem: Whenever the user 'clears (sets its value to NULL)' the modulegoal/modulefase/modulerslt sets the moduleid value to an empty string and the 'second key' as well. The problem is that the first keys is being used in multiple references. So clearing one of the references, mismatches the other (important) references. Is there any way to tell breeze to NOT clear the first key?
I'm building a form with input filters and all in Zend Framework 2. I'm using arrays to configure my inputs and filters and validators. So, say I have some input:
array(
'name' => 'foo',
'required' => true,
)
On the page, there's some jQuery code that might optionally hide this input. If it does, it hides and disables the input. On submit, var_dump on the form data gives foo => null (probably because it didn't actually submit in the post data and so the form input is never given a value). If the input is not hidden and not filled out then on submit it has foo => string '' (length=0).
I want to require the input to have a value if the input is used. So, are there some settings I can add to my config array that will allow null to pass validation, but reject the empty string value? Or do I need to write a custom validator?
Yes, you ought to use NotEmpty validator.
$inputFilter = new \Zend\InputFilter\InputFilter ();
$inputFilter->add ([
'name' => 'foo',
'validators' => [
[
'name' => 'not_empty',
'options' => [
'type' => 'string'
]
]
]
]);
$form->setInputFilter ($inputFilter);
Is posibble to have something like this? :
%div{"data-regex": "a/regular/expression"}
When I try to do this ways, I get this error:
syntax error, unexpected ':', expecting tASSOC
I tried this: %div{"data-regex": #{"a/regular/expression"}}, but is the same.
What you're probably looking for is:
%div{data: {regex: "a/regular/expression"} }
However it would be nice if you included the desired HTML in your question so we could know for sure. The other answer provided will also work, but this is especially nice if you want to provide many data attributes without repeating "data-" all over the place. That is, you can do:
%div{data: {regex: "a/reg/ex", attr2: "something", attr3: "something else" } }
Note, your problem is that the nice syntax in Ruby 1.9+ for Symbol keys in hashes doesn't work with strings preceding the colon.
{ a: 123 }
# => { :a => 123 }
{ :"a" => 123 }
# => { :a => 123 }
{ "a" => 123 }
# => { "a" => 123 }
{ "a": => 123 }
# => SyntaxError ...
To make sure that it works, you can try usual form to write a hash of parameters:
%div{:'data-regex' => "a/regular/expression"}
I guess, this may be applied to use in ruby 2.x:
%div{"data-regex": "a/regular/expression"}
I'm adding pg_search into a Rails app. I'm following the instructions on github and this railscast, but I've run into a problem.
I'm setting up a multi model search, and I have a basic implementation working. But I want to extend pg_seach to use its English dictionary.
I already have an initializer:
PgSearch.multisearch_options = {
:using => [:tsearch,:trigram],
:ignoring => :accents
}
So, from what I've read, it looks like adding the dictioary should be as simple as
PgSearch.multisearch_options = {
:using => [:tsearch => [:dictionary => "english"],:trigram],
:ignoring => :accents
}
But when I start my server
...config/initializers/pg_search.rb:2: syntax error, unexpected ']', expecting tASSOC (SyntaxError)
:using => [:tsearch => [:dictionary => "english"],:trigram],
I've tried swapping square for curly brackets, and all the other syntax permutations I can think of, but no luck.
What is the correct syntax here? And why aren't my attempts valid, as I've followed the syntax for scoped searches?
What you posted is not valid Ruby syntax.
You want something like this:
PgSearch.multisearch_options = {
:using => {
:tsearch => {
:dictionary => "english"
},
:trigram => {}
},
:ignoring => :accents
}
The reason is that you must use a Hash if you want to have key-value pairs. So essentially, pg_search allows 2 syntaxes:
:using => someArray # such as [:tsearch, :trigram]
which means "use tsearch and trigram, both with the default options"
or
:using => someHash # such as {:tsearch => optionsHash1, :trigram => optionsHash2}
which means "use tsearch with some options from optionsHash1, and use trigram with some options from OptionsHash2"
Let me know if there's anything I can do to clarify. It's pretty basic Ruby syntax, but I understand that the fact that pg_search accepts both formats can be confusing to those who aren't as familiar.
Using httparty I can get the following response:
puts Representative.find_by_zip(46544).inspect
-->
{"results"=>[{"name"=>"Joe Donnelly", "district"=>"2", "office"=>"1218 Longworth", "phone"=>"(202) 225-3915", "link"=>"http://donnelly.house.gov/", "state"=>"IN"}]
source of the example: http://railstips.org/blog/archives/2008/07/29/it-s-an-httparty-and-everyone-is-invited/
but I fail to access the data, for example:
Representative.find_by_zip(46544).inspect["name"] returns nil
How can I access individual elements of this response?
Object#inspect returns a string, not a hash. You want this:
Representative.find_by_zip(46544)['results'][0]['name']
This is what's going on: Representative#find_by_zip returns a Hash with just one index: 'results'. The item at 'results' is an array, which in this case only contains one element, so we use [0] to get the first (and only) element. That element is itself a hash that has the 'name' key, which points to the name of the first (and only) representative returned.
When you have complex hashes and arrays it's sometimes useful to format it in a more readable way to figure out how to get at the data you want:
{ "results" => [
{ "name" => "Joe Donnelly",
"district" => "2",
"office => "1218 Longworth",
"phone" => "(202) 225-3915",
"link" => "http://donnelly.house.gov/",
"state" => "IN"
}
]
}
That should make it more clear what's inside what here.
To Access the individual elements, You can use:-
If the response is JSON:-
You can use:-
response.parsed_response["key"]
If your response is a string then, you can use:-
data = JSON.parse(resp.body)
The response type depends, on the content type you are setting while requesting the data:-
'Content-Type' => 'application/json'
If you don't set the content type it returns response as string.