How to perform morphology analysis in RoR? - ruby-on-rails

I am looking for ways to turn single words to their infinitives inside models:
cats -> cat
sharpest -> sharp
etc.
Do you know of any gems or libraries that are able to do that?

String#singularize is providing : The reverse of pluralize, returns the singular form of a word in a string.
'posts'.singularize # => "post"
'octopi'.singularize # => "octopus"
'sheep'.singularize # => "sheep"
'word'.singularize # => "word"
'the blue mailmen'.singularize # => "the blue mailman"
'CamelOctopi'.singularize # => "CamelOctopus"
'leyes'.singularize(:es) # => "ley"
for String#pluralize : Returns the plural form of the word in the string.
'post'.pluralize # => "posts"
'octopus'.pluralize # => "octopi"
'sheep'.pluralize # => "sheep"
'words'.pluralize # => "words"
'the blue mailman'.pluralize # => "the blue mailmen"
'CamelOctopus'.pluralize # => "CamelOctopi"
'apple'.pluralize(1) # => "apple"
'apple'.pluralize(2) # => "apples"
'ley'.pluralize(:es) # => "leyes"
'ley'.pluralize(1, :es) # => "ley"
In addition you can also have a look at 'verbs' gem
Conjugates most common english verbs for all persons, tenses, standard
aspects, and modern moods (with active diathesis). Standard and
exceptional spelling rules are obeyed.

Related

Mongomapper human readable id

Is there any way to create human readable id for mongomapper
I mean replace 54114ac51d41c84fb900005a to id 1
Thanks
Try:
gem 'mongomapper_id2'
It’s a MongoMapper’s plugin to add auto incremented ids in MongoMapper’s documents.
Example:
# app/models/movie.rb
class Movie
include MongoMapper::Document
key :title, String
# Here is the mongomapper_id2
auto_increment!
end
movie = Movie.create(:title => 'The Simpsons Movie')
movie.id # BSON::ObjectId('4d1d150d30f2246bc6000001')
# Here is the mongomapper_id2
movie.id2
# => 1
movie2 = Movie.create(:title => 'Pirates of Silicon Valley')
movie2.id2
# => 2

Return a number from collection_select

I am using an input field with a collection, which is drawn from an array in the model. This works well, but I would like to return a different value to the actual column in the table. I'm using simple_form.
model
TASK_OPTIONS = %w(Detection Cloning Sequencing Primer_List Primer_Check)
view
<%= f.input :primer_task, :collection => Primer3Batch::TASK_OPTIONS, :label => 'Task' %>
I might want to return something like this:
{1 => 'Detection', 2 => 'Cloning'... etc
Or this:
{'AB' => 'Detection, 'C' => 'Cloning' ....
That is: the page will display Detection, Cloning etc but the database column will store 1,2 or AB, C
I've guessed it can be done with a hash but I can't quite work out the syntax.
a = []
%w(Detection Cloning Sequencing Primer_List Primer_Check).each.with_index(1) do |it,ind|
a << [ind,it]
end
Hash[a]
# => {1=>"Detection",
# 2=>"Cloning",
# 3=>"Sequencing",
# 4=>"Primer_List",
# 5=>"Primer_Check"}
Using Enumerable#each_with_object
a = %w(Detection Cloning Sequencing Primer_List Primer_Check)
a.each_with_object({}) {|it,h| h[a.index(it) + 1 ] = it }
# => {1=>"Detection",
# 2=>"Cloning",
# 3=>"Sequencing",
# 4=>"Primer_List",
# 5=>"Primer_Check"}

Rails console compare model instances

Is there a way to compare two instances of model like
Model.compare_by_name("model1", "model2") which would list the differing column fields
You can use ActiveRecord::Diff if you want a mapping of all the fields that differ and their values.
alice = User.create(:name => 'alice', :email_address => 'alice#example.org')
bob = User.create(:name => 'bob', :email_address => 'bob#example.org')
alice.diff?(bob) # => true
alice.diff(bob) # => {:name => ['alice', 'bob'], :email_address => ['alice#example.org', 'bob#example.org']}
alice.diff({:name => 'eve'}) # => {:name => ['alice', 'eve']}
There is no standard comparator for this. The standard ActiveModel comparator:
Returns true if comparison_object is the same exact object, or comparison_object is of the same type and self has an ID and it is equal to comparison_object.id.
You can write your own by using Hash#diff from activesupport. Something like the following should hopefully get you started:
def Model.compare_by_name(model1, model2)
find_by_name(model1).attributes.diff(find_by_name(model2).attributes)
end
Without using a library or defining a custom method, you can easily get a diff between two models.
For instance,
a = Foo.first
b = Foo.second
a.attributes = b.attributes
a.changes #=> {"id" => [1,2] }

Refactor this block of routes?

I have to manually redirect a set of URLs, but seems like there's got to be a more efficient way (in terms of # of lines) than what I've currently go.
match "/articles/care" => redirect("/articles/category/care")
match "/articles/food-diet" => redirect("/articles/category/food-diet")
match "/articles/basics" => redirect("/articles/category/basics")
match "/articles/training" => redirect("/articles/category/training")
match "/articles/recipes" => redirect("/articles/category/recipes")
match "/articles/life" => redirect("/articles/category/life")
Try this out:
for category in %w{ care food-diet training recipes life }
match "/articles/#{category}" => redirect("/articles/category/#{category}")
end

Is there find_or_create_by_ that takes a hash in Rails?

Here's some of my production code (I had to force line breaks):
task = Task.find_or_create_by_username_and_timestamp_and_des \
cription_and_driver_spec_and_driver_spec_origin(username,tim \
estamp,description,driver_spec,driver_spec_origin)
Yes, I'm trying to find or create a unique ActiveRecord::Base object. But in current form it's very ugly. Instead, I'd like to use something like this:
task = Task.SOME_METHOD :username => username, :timestamp => timestamp ...
I know about find_by_something key=>value, but it's not an option here. I need all values to be unique. Is there a method that'll do the same as find_or_create_by, but take a hash as an input? Or something else with similat semantics?
Rails 3.2 first introduced first_or_create to ActiveRecord. Not only does it have the requested functionality, but it also fits in the rest of the ActiveRecord relations:
Task.where(attributes).first_or_create
In Rails 3.0 and 3.1:
Task.where(attributes).first || Task.create(attributes)
In Rails 2.1 - 2.3:
Task.first(:conditions => attributes) || Task.create(attributes)
In the older versions, you could always write a method called find_or_create to encapsulate this if you'd like. Definitely done it myself in the past:
class Task
def self.find_or_create(attributes)
# add one of the implementations above
end
end
I also extend the #wuputah's method to take in an array of hashes, which is very useful when used inside db/seeds.rb
class ActiveRecord::Base
def self.find_or_create(attributes)
if attributes.is_a?(Array)
attributes.each do |attr|
self.find_or_create(attr)
end
else
self.first(:conditions => attributes) || self.create(attributes)
end
end
end
# Example
Country.find_or_create({:name => 'Aland Islands', :iso_code => 'AX'})
# take array of hashes
Country.find_or_create([
{:name => 'Aland Islands', :iso_code => 'AX'},
{:name => 'Albania', :iso_code => 'AL'},
{:name => 'Algeria', :iso_code => 'DZ'}
])

Resources