I used Sphinx plugin for searching and configure it
define_index do
indexes First_name, :sortable => true
set_property :min_prefix_len => 1
end
Here First_name is column name.
But I was getting error of "search daemon fails to run". And when I made the column name as symbol it runs perfectly.
define_index do
indexes :First_name, :sortable => true
set_property :min_prefix_len => 1
end
Please make it clear to me.
http://www.robertsosinski.com/2009/01/11/the-difference-between-ruby-symbols-and-strings/
I think your example don't work because in first variant First_name is not a string. It's variable
"First_name" - will be a string
BTW , the difference between string and a symbol is that multiple symbols representing a single value are unique whereas this is not true with strings. For example:
irb(term)> :symbol.object_id
=> 746921
irb(term)> :symbol.object_id
=> 746921
irb(term)> "string".object_id
=> 298788231
irb(main):011:0> "string".object_id
=> 297533890
Also, symbol equality comparison is faster then String equality comparison since they are the same object whereas in a strings the values need to be compared instead the object id.
indexes First_name, :sortable => true
here rails treat First_name as a constant variable not the column.
so you can use
indexes :First_name, :sortable => true
or
indexes "First_name", :sortable => true
or
change the column First_name to first_name and then you can do this
indexes first_name, :sortable => true
Related
I wan to get 2 url image from 2 devices. My model structure:
Compare: has_one :device1, has_one :device2
Device: has_one :image
Image: mount_uploader :image, ImageUploader
In query I want to get JSON array compares from query
#compares = Compare.any_of({:device1_id.in => arr_device_id},{:device2_id.in => arr_device_id})
I try: (title is attr_accessor)
Compare.any_of({:device1_id.in => arr_device_id},{:device2_id.in => arr_device_id}).only(:title => 'abc'). Result json is not contain field title
#compare.to_json(:include => [:device1,:device2]) => this include device1 and device2 but not include image of it.
#compare.to_json(:method => [:title => 'abc']) . Result json is not contain field title
Any solutions ? Thank for your help :D
Did you mean only(:title => "abc") is to select only field "title" ?
Then, the solution may be replacing it with only(:title)
If what you mean only is where title is "abc" then replace only(:title => "abc") by where(:title => "abc")
to_json should work then.
Given a table ZipCodeInfos with fields zipcode, state, city (all strings), where zipcode is unique:
zipcode,city,state
"10000", "Fooville", "AA"
"10001", "Smallville", "AA"
"10002", "Whoville", "BB"
What is the fastest way to generate a hash object of the entire table where the zipcode is a key like this:
{ "10000" => {:city => "Fooville", :state => "AA" },
"10001" => {:city => "Smallville", :state => "AA" },
"10002" => {:city => "Whoville", :state => "BB" } }
I know for a given record I can use .attributes to generate a hash with key,value pairs of field-names, field-values, for example Zipcode.first.attributes gives me
{"id" => 1, "zipcode" => "10000", "city" => "Fooville", "state => "AA" }
But, short of brute force iterating over each record (via .map), I cannot quite figure out how to create the desired hash with the zipcode as the key for each node of the hash.
This is the best I could come up with, and I suspect there is some nifty Ruby goodness that is faster?
zip_info_hash = {}
ZipCodeInfo.all.map{|x| zip_info_hash[x.zip] =
{'state' => x.state, 'city' => x.city }}
You could also try:
ZipCodeInfos.all.group_by &:zipcode
will get you a hash of zip code to array of ZipCodeInfos activerecords.
You can use inject method.
Here is what I generally use.
def visitors_name_email
visitors.inject({}) do |result, visitor|
result.merge(visitor.name => visitor.email)
end
end
I can't think of a way to avoid map here. I'd make only some minor changes to your code:
zip_info=Hash[*ZipCodeInfo.all
.map{|x| [x.zip, {:city => x.city, :state => x.state}]}
.flatten]
#models.map(&:attributes)) returns a list of hashes from each column to its value in the db
How do I limit it so that only specific columns are returns (e.g. just name and id?).
Also, how do I combine multiple columns to a new key => value pair? For example, if a user has first_name and last_name, the above would return
[{"first_name" => "foo", "last_name" => "bar"}] but I want it to be [{"name" => "foo bar"}]
How do I achieve this transformation? Thanks!
For the first part (limiting the attributes in the hash):
#models.map {|model| model.attributes.slice(:id, :name)}
For combining multiple attribute into a new attribute, the cleanest way is usually an accessor method:
class User < ActiveRecord::Base
def name
"#{first_name} #{last_name}"
end
end
Then build your hash manually during iteration:
#models.map {|model| {:id => model.id, :name => model.name}}
If you're using more than one attribute from the attributes hash, you can use merge:
#models.map do |model|
model.attributes.slice(:id, :first_name, :last_name).merge(:name => model.name)
end
Greetings,
I want to store some data in a redis db and don't know which way I should go. The data is equivalent to something like an address with the variables name, street and number. They will be stored under the lower cased name as key, there won't be doublets.
Now, should I save it as a list or should I serialize the hash ({:name => 'foo', :street => 'bar', :number => 'baz'} for example) with JSON/Marshall and simply store that?
Regards
Tobias
Using an encoded json object is a pretty good idea. You can see some examples in hurl — check out how the models are saved.
Redis hashes are nice too, especially if you need atomic operations on hash values.
Also you can use something like Nest to help you DRY up your keys:
addresses = Nest.new("Address", Redis.new)
this_address = addresses[1]
# => "Address:1"
this_address.hset(:name, "foo")
this_address.hset(:street, "bar")
this_address.hgetall
# => {"name" => "foo", "street" => "bar"}
If you need something more advanced, there's Ohm, which maps Ruby classes to Redis:
class Address < Ohm::Model
attribute :name
attribute :street
attribute :number
end
# Create
Address.create(:name => "foo", :street => "bar")
# Find by ID
Address[1]
# Find all addresses with name "foo"
class Address < Ohm::Model
attribute :name
attribute :street
attribute :number
index :name
end
Address.find(:name => "foo")
# => Array-like with all the Address objects
I'm constantly doing this
puts “The temperature is “ + String(temperature) + “.”
in my debugging code, and another option is to use interpolation
puts “The temperature is #{temperature}.”
is there any less cumbersome way to do this?
Edit: This is just for debugging, if that matters.
None that are all that worthwhile for small cases like that.
Though, you should prefer interpolation as it's less expensive than concatenation.
The best way to insert dynamic variables into strings is
#interpolation
"foo #{my_var} bar"
It will call the to_s method on whatever object the expression returns and insert that string. It really the same as
#concatenation
"foo " + my_var.to_s + " bar"
But, as wfarr metioned, its faster to do interpolation. Easier to read too.
A slightly different approach is to use assertions in automated tests.
For example using Test::Unit :-
assert_equal 25, temperature
I find that using automated tests dramatically cuts down on the amount of debugging code I have to write.
Use Kernel#p
p temperature #=> 10.25
When I'm debugging, I often label such statements just by copying the line, and using inserting a colon, making the variable into a symbol.
p :attributes #=> :attributes
p attributes #=> { :mood => "happy", 5 => [] }
Or
p [:location, location] #=> [ :location, "# work" ]
Note that Kernel#p calls #inspect on its arguments, instead of #to_s, but this normally provides more useful debugging info anyway.
I highly recommend to use irbtools gem which includes awesome_print or just awesome_print.
I personally find it faster and less cumbersome to use in dev, then using interpolated strings, thou sometimes that's the only way to go.
You can do this on any object and it will give you a nicely formatted otput be that array, string or hash or even any other complex object that you may have - like 3-dimentional array printted as a tree structure. In order to have it awailable in your rails env - just include it in the Gemfile in the development group, or add it to .irbrc - to always have it in your irb console. Then just do
require "awesome_print"
ap MyGreatObject
here is a sample output from one of my projects
ap Address
class Address < ActiveRecord::Base {
:id => :integer,
:address_line_1 => :string,
:address_line_2 => :string,
:address_line_3 => :string,
:city => :string,
:state => :string,
:zip => :string,
:country => :string,
:attn => :string,
:category_id => :integer,
:addressable_id => :integer,
:addressable_type => :string,
:created_at => :datetime,
:updated_at => :datetime
}
ap Address.first
Address Load (1.0ms) SELECT `addresses`.* FROM `addresses` LIMIT 1
#<Address:0x7bc5a00> {
:id => 1,
:address_line_1 => "1 Sample Drive",
:address_line_2 => nil,
:address_line_3 => nil,
:city => "Chicago",
:state => "IL",
:zip => "60625",
:country => "USA",
:attn => nil,
:category_id => 1,
:addressable_id => 1,
:addressable_type => "Warehouse",
:created_at => Tue, 10 Jan 2012 14:42:20 CST -06:00,
:updated_at => Tue, 17 Jan 2012 15:03:20 CST -06:00
}
There's always the possibility to use printf style formatting:
"The temperature is %s" % temperature
This would allow for finer formatting of numbers, etc. as well. But honestly, how much less "cumbersome" than using #{} interpolation can you expect to get?
Another way is to do something stupid like this:
"The temperature is %s." % temperature.to_s
Personally I'd use interpolation