Rails titlecase only upward - ruby-on-rails-3

Is there any way to modify the titlecase method that comes with Rails so that it capitalizes everything it should but never takes anything that was already capitalized and makes it lowercase? E.g. The title "ABC photo shoot" should become "ABC Photo Shoot" and not "Abc Photo Shoot".

As I know there is no such built-in method in Rails. I just construct a custom one.
class String
def smart_capitalize
ws = self.split
ws.each do |w|
w.capitalize! unless w.match(/[A-Z]/)
end
ws.join(' ')
end
end
"ABC photo".smart_capitalize
#=> "ABC Photo"
"iPad is made by Apple but not IBM".smart_capitalize
#=> "iPad Is Made By Apple But Not IBM"
Add: To exclude unimportant words as per Associated Press Style
class String
def smart_capitalize
ex = %w{a an and at but by for in nor of on or so the to up yet}
ws = self.split
ws.each do |w|
unless w.match(/[A-Z]/) || ex.include?(w)
w.capitalize!
end
end
ws.first.capitalize!
ws.last.capitalize!
ws.join(' ')
end
end
"a dog is not a cat".smart_capitalize
#=> "A Dog Is Not a Cat"
"Turn the iPad on".smart_capitalize
#=> "Turn the iPad On"

Related

Use the same model in two active admin classes

I'm working on an ActiveAdmin app for a large production application. I'm currently trying to use the same model for two activeadmin "entities".
So, say I have
class Person < ActiveRecord::Base
scope :special, where(:is_special => true)
scope :ordinary, where(:is_special => false)
end
Can I do something like
ActiveAdmin.register Person, :name => "Special People" do
# columns, filters for special people
controller do
def scoped_collection
Person.special
end
end
end
ActiveAdmin.register Person, :name => "Ordinary People" do
# columns, filters for ordinary people
controller do
def scoped_collection
Person.ordinary
end
end
end
(I'm making up the syntax a bit here to explain what I want to do.)
The two types of people would appear as menu items and different CRUD interfaces as defined in the ActiveAdmin.register block. They would just have the same underlying model.
Active Admin model Code:
ActiveAdmin.register Person, as: "Special People" do
scope :Special, default: true do |person|
person = Person.special
end
controller do
def scoped_collection
Person.special
end
end
end
ActiveAdmin.register Person, as: "Ordinary People" do
scope :Ordinary, default: true do |person|
person = Person.ordinary
end
controller do
def scoped_collection
Person.ordinary
end
end
end
Now in routes:
match '/admin/special_people/scoped_collection/:id' => 'admin/special_people#scoped_collection'
match '/admin/ordinary_people/scoped_collection/:id' => 'admin/ordinary_people#scoped_collection'
Try with above changes. Hope this would solve your issues. Thanks.

How can I troubleshoot this JSON method in DataTables gem?

I'm trying to implement the Railscast 340 that demos how to use DataTables, which looks like an awesome gem for my project.
My model is different, of course; but the datatables class the Mr Bates builds (very quickly), in order to do server-side processing, is rather complicated to follow. I got the source code, and basically attempted to follow along. My view comes up with zero records (but there are > 10,000 records), but does not break.
However, here is what the error message output from the rails server says just before it stops:
NameError (undefined local variable or method `genotypes' for #<GenotypesDatatable:0xa9e852c>):
app/datatables/genotypes_datatable.rb:12:in `as_json'
app/controllers/genotypes_controller.rb:8:in `block (2 levels) in index'
app/controllers/genotypes_controller.rb:6:in `index'
Just before this, there appears to be this JSON error, which starts:
Started GET "/genotypes.json?sEcho=1&iColumns=8&sColumns=&iDisplayStart=0&iDisplayLength=10&mDataProp_0=...
The relevant part of the genotypes controller looks like this:
def index
respond_to do |format|
format.html
format.json { render json: GenotypesDatatable.new(view_context) }
end
end
And my genotypes model looks like:
class Genotype < ActiveRecord::Base
attr_accessible :allele1, :allele2, :run_date
belongs_to :gmarkers
belongs_to :gsamples
end
My datatables class is given below. This is from Mr Bates code, modified (most likely incorrectly) to replace his Products model with my Genotypes model:
class GenotypesDatatable
delegate :params, :h, :link_to, to: :#view
def initialize(view)
#view = view
end
def as_json(options = {})
{
sEcho: params[:sEcho].to_i,
iTotalRecords: Genotype.count,
iTotalDisplayRecords: genotypes.total_entries,
aaData: data
}
end
private
def data
genotypes.map do |genotype|
[
link_to(genotype.name, genotype),
h(genotype.category),
h(genotype.released_on.strftime("%B %e, %Y")),
genotype.run_date
]
end
end
def Genotypes
#Genotypes ||= fetch_Genotypes
end
def fetch_genotypes
genotypes = Genotype.order("#{sort_column} #{sort_direction}")
genotypes = genotypes.page(page).per_page(per_page)
if params[:sSearch].present?
genotypes = genotypes.where("name like :search or category like :search", search: "%#{params[:sSearch]}%")
end
genotypes
end
def page
params[:iDisplayStart].to_i/per_page + 1
end
def per_page
params[:iDisplayLength].to_i > 0 ? params[:iDisplayLength].to_i : 10
end
def sort_column
columns = %w[gmarker gsample allele1 allele2 run_date]
columns[params[:iSortCol_0].to_i]
end
def sort_direction
params[:sSortDir_0] == "desc" ? "desc" : "asc"
end
end
Any hints on how to troubleshoot (or fix!) this error much appreciated! (Getting this working for my project would be awesome!)
TIA,
rixter
I'm not sure if this is it, but your class has a Genotype method with capital G, it should be all lowercase.

rails singularize to a / an

Is there a method that works similar to singularize to prepend "a" or "an according to the word?
like f(apple) # => an apple
f(carpet) #=> a carpet
Look here http://deveiate.org/projects/Linguistics/wiki/English and check out this question
If you need something simpler, something that will for instance prepend "an" if a word starts with vowel, you can use my one liner:
String.class_eval { def prepend; %w(a e i o u).include?(downcase.first) ? "an #{self}" : "a #{self}"; end }
Put this in a file prepend.rb in config/initializers folder of your application.
Then you will be able to use
"carrot".prepend => "a carrot"
"apple".prepend => "an apple"

Rails 3: Sortable Columns

I'm following Railscasts #228 in Rails 3.0.5 and ruby 1.9.2p180.
I have copied code near verbatim from the verbatim with the exception of changing the class name from Product to Player. I'm also skipping the last portion where Ryan adds arrows to denote the sort direction. I'm able to load the correct index page and see all of the desired URL's with the desired parameters (direction and sort), but nothing is actually happening on click. The URL is changing, but the page is not reloading.
Here is my code:
ApplicationHelper
def sortable(column, title = nil)
title ||= column.titleize
direction = (column == params[:sort] && params[:direction] == "asc") ? "desc" : "asc"
link_to title, :sort => column, :direction => direction
end
PlayersController
def index
#players = Player.order(sort_column + ' ' + sort_direction)
end
private
def find_team
session[:team] ||= Team.new
end
def sort_column
Player.column_names.include?(params[:sort]) ? params[:sort] : "name_e"
end
def sort_direction
%w[asc desc].include?(params[:direction]) ? params[:direction] : "asc"
end
Thanks for your help!
Edit: As requested, HTML code. You can see that the link for Position is currently desc, as I am at: http://localhost:3000/players?direction=asc&sort=abb_pos. However, no actual sorting has occurred for this column, or any other column.
<th>Name</th>
<th>Team</th>
<th>Position</th>
<th>Height</th>
<th>Weight</th>
Nathan
I'd suggest doing this first thing:
def index
order = sort_column + ' ' + sort_direction
puts "-- order:'#{order}'"
...
end
Click the links and then look in server's console for that "--" output. Most probably there's a logical flaw somewhere that makes the actual compiled ORDER clause always be the same. Links themselves look perfectly okay. Unless there's a # character in the links somewhere, all clicks should work (i.e. the browser should reload the content).
As for the problem in general, there's a gem called handles_sortable_columns, which gets you sortable columns for no effort at all.
Alex
Found the issue. I had the following code in my player model:
Player.rb
default_scope :order => 'name_e'
As a result, the SQL search generated looked like this:
SELECT `players`.* FROM `players` ORDER BY name_e, avg_points desc

How to set Mongoid fields from within the class

I am suddenly completely lost with scope of variables in Rails with Mongoid. (Probably due to a lack of coffee).
All I want, is a way to set certain fields from within the application, but the only way I can find to do this, is by calling write_attribute.
class Example
include Mongoid::Document
field :foo
def bar
#foo = "meh"
end
def hmpf
foo = "blah"
end
def baz
write_attribute(:foo, "meh")
end
end
e.bar #=> "meh"
e.foo #=> nil
e.hmpf #=> "blah"
e.foo #=> nil
e.baz #=> [nil, "meh"]
e.foo #=> "meh"
Am I using the scope wrong? Why will running foo = "bar" not set the field from within, it works from outside: e.foo = "blah" works trough the magic methods.
Try adding self to your attribute references when working in your model's instance methods:
def hmpf
self.foo = "blah"
end
Should do the trick.