I've setup everything according to README and here's my model
class Building
include Gmaps4rails::ActsAsGmappable
include Mongoid::Document
include Geocoder::Model::Mongoid
acts_as_gmappable :lat => 'location[0]', :lng => 'location[1]',
:address => "address", :normalized_address => "full_address",
:msg => "Sorry, not even Google could figure out where that is"
field :gmaps, :type => Boolean
field :address, :type => String, :default => ""
field :city, :type => String, :default => ""
field :province, :type => String, :default => ""
field :country, :type => String, :default => ""
field :postal_code, :type => Integer
field :location, :type => Array, spacial: {lat: :latitude, lng: :longitude, return_array: true }
## Building index
index({location: "2d"})
def full_address
"#{address}, #{city}, #{province}, #{country}, #{postal_code}"
end
def gmaps4rails_address
full_address
end
end
the controller
#hash = Gmaps4rails.build_markers(#building) do |building, marker|
marker.lat building.location[0]
marker.lng building.location[1]
end
and the view
= gmaps4rails( "markers" => { "data" => #hash.to_json, "options" => { "draggable" => true }})
when I access the control, gives me "uninitialized constant Gmaps4rails::ActsAsGmappable"
There is not a ActsAsGmappable module/class defined in the gem, hence the error.
It seems that it was removed in newer versions of the gem. Try removing that line and see if everything works.
Related
I return all information in a scream as JSON.
I want to return how long ago it was created.
include ActionView::Helpers::DateHelper
def as_json(options={})
super(:only => [:id, :yell_type, :status, :payment_type],
:include => {
:trade_offer => {:only => [:id, :title, :description, :price],
:include => [:photos => {:only => [:id, :url]}]
},
:categories => {:only => [:id, :name]},
:user => {:only => [:id, :name, :avatar]}
},
:methods => [ times_ago(:create_at) ]
)
end
def times_ago(create_at)
time_ago_in_words(create_at)
end
This returns an error:
comparison of Symbol with Time failed
How should I do that?
You can add methods on the same level as include and only. So the return value of the method will be passed in the JSON too. In this case, you should implement a method times_ago in the model that returns what you want.
def as_json(options={})
super(
:only => [:id, :yell_type, :status, :payment_type],
:include => {
:trade_offer => {:only => [:id, :title, :description, :price],
:include => [:photos => {:only => [:id, :url]}]
},
:categories => {:only => [:id, :name]},
:user => {:only => [:id, :name, :avatar]}
},
:methods: [ :times_ago ]
)
end
I have a Rails application that is now set up with ElasticSearch and the Tire gem to do searching on a model and I was wondering how I should set up my application to do fuzzy string matching on certain indexes in the model. I have my model set up to index on things like title, description, etc. but I want to do fuzzy string matching on some of those and I'm not sure where to do this at. I will include my code below if you would like to comment! Thanks!
In the controller:
def search
#resource = Resource.search(params[:q], :page => (params[:page] || 1),
:per_page =>15, load: true )
end
In the Model:
class Resource < ActiveRecord::Base
include Tire::Model::Search
include Tire::Model::Callbacks
belongs_to :user
has_many :resource_views, :class_name => 'UserResourceView'
has_reputation :votes, source: :user, aggregated_by: :sum
attr_accessible :title, :description, :link, :tag_list, :user_id, :youtubeID
acts_as_taggable
mapping do
indexes :id, :index => :not_analyzed
indexes :title, :analyzer => 'snowball', :boost => 40
indexes :tag_list, :analyzer => 'snowball', :boost => 8
indexes :description, :analyzer => 'snowball', :boost => 2
indexes :user_id, :analyzer => 'snowball'
end
end
Try creating custom analyzers to achieve other stemming features, etc.
Check out my example (this example also uses Mongoid & attachments, don't look at it if you don't need it):
class Document
include Mongoid::Document
include Mongoid::Timestamps
include Tire::Model::Search
include Tire::Model::Callbacks
field :filename, type: String
field :md5, type: String
field :tags, type: String
field :size, type: String
index({md5: 1}, {unique: true})
validates_uniqueness_of :md5
DEFAULT_PAGE_SIZE = 10
settings :analysis => {
:filter => {
:ngram_filter => {
:type => "edgeNGram",
:min_gram => 2,
:max_gram => 12
},
:custom_word_delimiter => {
:type => "word_delimiter",
:preserve_original => "true",
:catenate_all => "true",
}
}, :analyzer => {
:index_ngram_analyzer => {
:type => "custom",
:tokenizer => "standard",
:filter => ["lowercase", "ngram_filter", "asciifolding", "custom_word_delimiter"]
},
:search_ngram_analyzer => {
:type => "custom",
:tokenizer => "standard",
:filter => ["standard", "lowercase", "ngram_filter", "custom_word_delimiter"]
},
:suggestions => {
:tokenizer => "standard",
:filter => ["suggestions_shingle"]
}
}
} do
mapping {
indexes :id, index: :not_analyzed
indexes :filename, :type => 'string', :store => 'yes', :boost => 100, :search_analyzer => :search_ngram_analyzer, :index_analyzer => :index_ngram_analyzer
indexes :tags, :type => 'string', :store => 'yes', :search_analyzer => :search_ngram_analyzer, :index_analyzer => :index_ngram_analyzer
indexes :attachment, :type => 'attachment',
:fields => {
:content_type => {:store => 'yes'},
:author => {:store => 'yes', :analyzer => 'keyword'},
:title => {:store => 'yes'},
:attachment => {:term_vector => 'with_positions_offsets', :boost => 90, :store => 'yes', :search_analyzer => :search_ngram_analyzer, :index_analyzer => :index_ngram_analyzer},
:date => {:store => 'yes'}
}
}
end
def to_indexed_json
self.to_json(:methods => [:attachment])
end
def attachment
path_to_file = "#{Rails.application.config.document_library}#{path}/#{filename}"
Base64.encode64(open(path_to_file) { |file| file.read })
end
def self.search(query, options)
tire.search do
query { string "#{query}", :default_operator => :AND, :default_field => 'attachment', :fields => ['filename', 'attachment', 'tags'] }
highlight :attachment
page = (options[:page] || 1).to_i
search_size = options[:per_page] || DEFAULT_PAGE_SIZE
from (page -1) * search_size
size search_size
sort { by :_score, :desc }
if (options[:facet])
filter :terms, :tags => [options[:facet]]
facet 'global-tags', :global => true do
terms :tags
end
facet 'current-tags' do
terms :tags
end
end
end
end
end
Hope it helps,
I need a model-level validation for Zip codes in USA and Canada. This code makes me feel bad:
zip_regex_usa = %r{\d{5}(-\d{4})?}
zip_regex_canada = %r{[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d}
validates :shipping_zip, :presence => true, :format => { :with => zip_regex_usa }, :if => :shipping_to_usa?
validates :shipping_zip, :presence => true, :format => { :with => zip_regex_canada }, :if => :shipping_to_canada?
validates :billing_zip, :presence => true, :format => { :with => zip_regex_usa }, :if => :billing_to_usa?
validates :billing_zip, :presence => true, :format => { :with => zip_regex_canada }, :if => :billing_to_canada?
def shipping_to_usa?
shipping_country == 'US'
end
def billing_to_usa?
billing_country == 'US'
end
def shipping_to_canada?
shipping_country == 'CA'
end
def billing_to_canada?
billing_country == 'CA'
end
How to make this code more elegant, writing a single validation line for each field?
You can use gem validates_as_postal_code
It allows you to check zip codes like this:
class Person < ActiveRecord::Base
validates_as_postal_code :postal_code, :country => "CA", :allow_blank => true
end
and there're more options
EDIT:
There's also one nice gem: going_postal check it out!
I pulled some bits together into this gem: validates_zipcode.
It currently supports 259 countries zipcode formats and plays nice with Rails 3 & 4.
You can use it like this:
class Address < ActiveRecord::Base
validates_zipcode :zipcode
validates :zipcode, zipcode: true
validates :zipcode, zipcode: { country_code: :ru }
validates :zipcode, zipcode: { country_code_attribute: :my_zipcode }
end
Hello
I am using Ruby on rails and JQgrid. Everything works fine but when the grid load the data it is sorted in a way I don't want. I need to be sorted descendent in the ID column.
I was not the one who developed this software so I don't know exactly what to change. This code is in the helper of the quote controller and I think here is where I have to change it. Someone told me to use Quote.order('id DESC') which is in the last line. I put it in the second line but nor of them is working properly. Could someone please tell me what needs to be added in order to accomplish it? There is also code in javascript. But that is very complex. I think I don't need to change that.
I really appreciate. I have more than 2 moths trying to solve it. Thanks.
def format_quote_grid!
Quote.grid.update({
:title => "Quotes",
:pager => true,
:search_toolbar => :hidden,
:resizable => false,
:height => :auto,
:except => [:contacts],
:rows_per_page => 10}) { |grid|
grid.column :id, :label => "Number", :width => 50#, :proc => lambda {|record| link_to record.number, quote_path(record) }
grid.column :job_name, :width => 140, :proc => lambda {|record| link_to record.job_name, quote_path(record) }
grid.column :category, :width => 60
grid.column :needs_installation, :width => 60
grid.column :contact_id, :hidden => true
grid.column :business_id, :hidden => true
grid.column :contact_name, :label => "Contact", :width => 100, :sortable => false, :proc => lambda {|record| link_to(record.contact.name, record.contact) if record.contact.present? }
grid.column :business_name, :label => "Business", :width => 100, :sortable => false, :proc => lambda {|record| link_to(record.business.name, record.business) if record.business.present? }
grid.column :scope_of_work_id, :hidden => true
grid.column :markup, :hidden => true
grid.column :notes, :hidden => true
grid.column :shred, :hidden => true
grid.column :printed_at, :hidden => true
grid.column :created_at, :hidden => true
grid.column :updated_at, :hidden => true
grid.column :user_id, :hidden => true
grid.column :actions, :width => 200, :sortable => false, :searchable => false, :proc => lambda {|record|
permissioned_actions(record) do |p|
p.show_link
p.link('Printable', printable_quote_path(record), :show, record)
p.edit_link
p.destroy_link
p.link('RFQ', request_for_quote_path(record.scope_of_work.request_for_quote_id), :show, record.scope_of_work) if record.scope_of_work.present?
p.correspondence_link
p.resources_link
p.link(record.work_order.number, work_order_path(record)) if record.work_order
end
}
Quote.order('id DESC') #hecho por mi
}
end
Ok, from one of your earlier posts on this subject, it seems you are using Gridify.
Gridify seems to support the following options:
:sort_by # name of sort column of next request
:sort_order # sort direction of next request, 'asc' or 'desc' ('asc')
So, I would add the following just below :except => [:contacts],
:sort_by => :id,
:sort_order => :desc,
Hope this helps.
What am I doing wrong here? The forms work but keep getting "undefined method `to_i' for :street1:Symbol" when trying to seed data.
EDIT = If I do everything as a singular address (has_one instead of has_many) seed works.
EDIT 2 = See answer below for others...
address.rb
class Address < ActiveRecord::Base
attr_accessible :street1, :street2, :city, :state, :zipcode, :deleted_at, :addressable_type, :addressable_id, :current, :full_address, :address_type
belongs_to :addressable, :polymorphic => true
scope :vendor, where("address_type='Vendor'")
before_save :update_full_address
def update_full_address
unless self.street2.blank?
street = self.street1 + "<br />" + self.street2 + "<br />"
else
street = self.street1 + "<br />"
end
citystatezip = self.city + ", " + self.state + " " + self.zipcode
self.full_address = street + citystatezip
end
end
vendor.rb
class Vendor < ActiveRecord::Base
attr_accessible :name, :contact, :phone, :addresses_attributes
has_many :addresses, :as => :addressable
accepts_nested_attributes_for :addresses, :allow_destroy => true, :reject_if => proc { |obj| obj.blank? }
end
seed data
require 'faker'
Vendor.delete_all
["Company A", "Company B", "Company C", "Company D"].each do |c|
params = {:vendor =>
{
:name => c,
:contact => Faker::Name.name,
:phone => Faker::PhoneNumber.phone_number,
:addresses_attributes => {
:street1 => Faker::Address.street_address,
:city => Faker::Address.city,
:state => Faker::Address.us_state_abbr,
:zipcode => Faker::Address.zip_code,
:address_type => "Vendor"
}
}
}
Vendor.create!(params[:vendor])
end
Note the [] for an array when dealing with has_many.
require 'faker'
Vendor.delete_all
["Company A", "Company B", "Company C", "Company D"].each do |c|
params = {:vendor =>
{
:name => c,
:contact => Faker::Name.name,
:phone => Faker::PhoneNumber.phone_number,
:addresses_attributes => [{
:street1 => Faker::Address.street_address,
:city => Faker::Address.city,
:state => Faker::Address.us_state_abbr,
:zipcode => Faker::Address.zip_code,
:address_type => "Vendor"
}]
}
}
Vendor.create!(params[:vendor])
end
accepts_nested_attributes_for :foo is so that you can create forms which create associated records. When you're building things in code, there's no need to use this. You can create the associated records using the association names instead of "address_attributes". Here's one way of doing it, but Rails does expose a bunch of ways of doing this same thing...
["Company A", "Company B", "Company C", "Company D"].each do |c|
vendor_address = Address.new :street1 => Faker::Address.street_address,
:city => Faker::Address.city,
:state => Faker::Address.us_state_abbr,
:zipcode => Faker::Address.zip_code,
:address_type => "Vendor"
Vendor.create! :name => c,
:contact => Faker::Name.name,
:phone => Faker::PhoneNumber.phone_number,
:addresses => [vendor_address]
end
If you are wanting to try and use the nested attributes way, then you don't need the :vendor => {} part of the hash, you can go straight into the params, and you need addresses_attributes to be an array, not a hash.