Extending YAML alias anchors - ruby-on-rails-3

I'm trying to construct dynamic YAML to return strings, I'm wondering if it is possible to do something like this with YAML?
en:
occupation: "Studying #{department} at %{university} %{*speciality}"
speciality: &speciality "specialising in %{subject}"
expected output
I18n.t(:occupation, :department => "Computer Science",
:university => "Staffordshire University",
:subject => "Ruby")
#=> "Studying Computer Science at Staffordshire University specialising in Ruby"
I18n.t(:occupation, :department => "Computer Science",
:university => "Staffordshire University",
:subject => nil)
#=> "Studying Computer Science at Staffordshire University"
Currently the only way I think this may be posible is
subject = "Ruby"
I18n.t(:occupation, :department => "Computer Science",
:university => "Staffordshire University",
:subject => (
I18n.t(:speciality, :subject => subject) if subject
))
#=> "Studying Computer Science at Staffordshire University specialising in Ruby"

Related

OMDb API Rotten Tomatoes

I believe this may just be a bug in the OMDb API. But I am hoping that someone can point out the errors in my ways.
I am trying to include the Rotten Tomatoes Ratings in a output. But no matter what options I try I don't get anything.
curl http://www.omdbapi.com/?t=Iron+Man&y=&plot=short&tomatoes=true&r=json
Output:
{
:Title => "Iron Man",
:Year => "2008",
:Rated => "PG-13",
:Released => "02 May 2008",
:Runtime => "126 min",
:Genre => "Action, Adventure, Sci-Fi",
:Director => "Jon Favreau",
:Writer => "Mark Fergus (screenplay), Hawk Ostby (screenplay), Art Marcum (screenplay), Matt Holloway (screenplay), Stan Lee (characters), Don Heck (characters), Larry Lieber (characters), Jack Kirby (characters)",
:Actors => "Robert Downey Jr., Terrence Howard, Jeff Bridges, Gwyneth Paltrow",
:Plot => "After being held captive in an Afghan cave, an industrialist creates a unique weaponized suit of armor to fight evil.",
:Language => "English, Persian, Urdu, Arabic, Hungarian",
:Country => "USA",
:Awards => "Nominated for 2 Oscars. Another 17 wins & 52 nominations.",
:Poster => "http://ia.media-imdb.com/images/M/MV5BMTczNTI2ODUwOF5BMl5BanBnXkFtZTcwMTU0NTIzMw##._V1_SX300.jpg",
:Metascore => "79",
:imdbRating => "7.9",
:imdbVotes => "629,489",
:imdbID => "tt0371746",
:Type => "movie",
:Response => "True"
}
Reference:
http://www.omdbapi.com/
Update
In case anyone runs across this (me) again. Here's the expected output with tomatoes:
{
:Title => "Iron Man",
:Year => "2008",
:Rated => "PG-13",
:Released => "02 May 2008",
:Runtime => "126 min",
:Genre => "Action, Adventure, Sci-Fi",
:Director => "Jon Favreau",
:Writer => "Mark Fergus (screenplay), Hawk Ostby (screenplay), Art Marcum (screenplay), Matt Holloway (screenplay), Stan Lee (characters), Don Heck (characters), Larry Lieber (characters), Jack Kirby (characters)",
:Actors => "Robert Downey Jr., Terrence Howard, Jeff Bridges, Gwyneth Paltrow",
:Plot => "After being held captive in an Afghan cave, an industrialist creates a unique weaponized suit of armor to fight evil.",
:Language => "English, Persian, Urdu, Arabic, Hungarian",
:Country => "USA",
:Awards => "Nominated for 2 Oscars. Another 19 wins & 58 nominations.",
:Poster => "http://ia.media-imdb.com/images/M/MV5BMTczNTI2ODUwOF5BMl5BanBnXkFtZTcwMTU0NTIzMw##._V1_SX300.jpg",
:Metascore => "79",
:imdbRating => "7.9",
:imdbVotes => "635,229",
:imdbID => "tt0371746",
:Type => "movie",
:tomatoMeter => "94",
:tomatoImage => "certified",
:tomatoRating => "7.7",
:tomatoReviews => "266",
:tomatoFresh => "249",
:tomatoRotten => "17",
:tomatoConsensus => "Director Jon Favreau and star Robert Downey Jr. make this smart, high impact superhero movie one that even non-comics fans can enjoy.",
:tomatoUserMeter => "91",
:tomatoUserRating => "4.2",
:tomatoUserReviews => "1072111",
:DVD => "30 Sep 2008",
:BoxOffice => "$318.3M",
:Production => "Paramount Pictures",
:Website => "http://www.ironmanmovie.com/",
:Response => "True"
}
Well, you have to wrap your url inside the quote. Otherwise the & causing you the problem by breaking the command on that position.
curl "http://www.omdbapi.com/?t=Iron+Man&y=&plot=short&tomatoes=true&r=json"

Rails: Being frustrated with NoMethodError (undefined method...) error

I have a model Team and Division described as a division should have many teams:
class Team < ActiveRecord::Base
belongs_to :division
has_attached_file :logo, :styles => { :large => "120x180>", :thumb => "100x100>", :tiny => "25x25>" },
:url => "/assets/images/:style/teams/#{self.division.name}/:basename.:extension",
:path => ":rails_root/public/assets/images/teams/#{self.division.name}/:basename.:extension"
end
class Division < ActiveRecord::Base
has_many :teams
end
I want to get the name of division of the team by using: #{self.division.name} to include in the string but it doesn't work at all.
Error given:
NoMethodError (undefined method `division' for #<Class:0x007f80179b68f8>):
Even when I use #{self.name} to get the name of the team, but it return only the class name: "Team". In console, I call them just fine:
1.9.3p194 :009 > team = Team.find(4)
Team Load (0.3ms) SELECT `teams`.* FROM `teams` WHERE `teams`.`id` = 4 LIMIT 1
=> #<Team id: 4, name: "Arsenal F.C.", league_id: nil, division_id: 1, stadium_id: 2, history: "This is Arsenal F.C. history file", wins: 1, losses: 1, win_percentage: 1.0, created_at: "2012-08-25 09:25:22", updated_at: "2012-08-27 01:54:08", logo_file_size: 29303, logo_updated_at: "2012-08-27 01:54:08", logo_content_type: "image/png", logo_file_name: "arsenal.png">
1.9.3p194 :010 > team.name
=> "Arsenal F.C."
1.9.3p194 :011 > team.division.name
Division Load (0.3ms) SELECT `divisions`.* FROM `divisions` WHERE `divisions`.`id` = 1 LIMIT 1
=> "English Premier Division"
1.9.3p194 :012 >
I am trying to call self.name (name of the team) or self.division.name (name of the division of the team) in team.rb, not in a controller.
Any idea why? Because of the self hasn't loaded yet? How to solve this?
Update: I really like shioyama's solution because we can pass Proc to paperclip. However, my rails_admin and paperclip and this solution seem still throwing error about gsub on the form. I found another thread Dynamic use of :default_url in Paperclip that will cover my problem. shioyama's solution works fine without rails_admin.
When you use self inside a class definition, it refers to the class itself, not to an instance of that class. To get at the instance you have to use a lambda:
has_attached_file :logo,
:styles => { :large => "120x180>", :thumb => "100x100>", :tiny => "25x25>" },
:url => lamda { |attachment|
team = attachment.instance
"/assets/images/:style/teams/#{team.division.name}/:basename.:extension"
},
:path => lambda { |attachment|
team = attachment.instance
":rails_root/public/assets/images/teams/#{team.division.name}/:basename.:extension"
}
attachment.instance gets the instance that the attachment is attached to (in this case an instance of the Team class). See the paperclip documentation.
See also this answer: can you pass self to lambda in rails?

Rails 3.1 - before filter and database error

I'm having some trouble with lazy loading, i'm pretty sure of it ... maybe you could point out to me where I've failed.
def setup_guild
if params[:guild]
#guild = Guild.where(:short_name => params[:guild].upcase).first
if #guild.nil?
puts "no guild with short name #{params[:guild]} found"
redirect_to root_path
else
#title = t "layout.guild_title", :guild_name => (#guild.name).capitalize
end
else
#guild = nil
end
end
Which is called in ApplicationController as a before filter.
At first I used Guild.find_with_short_name, but I had the same dumb answer as now ... that is :
undefined method `capitalize' for nil:NilClass
app/controllers/application_controller.rb:29:in `setup_guild'
Which is, you'd guess the #title line up there.
The thing is, if I try something similar in the console I get the expected result
ruby-1.9.2-p0 > guild = Guild.where(:short_name => "ICPT").first
Guild Load (0.5ms) SELECT "guilds".* FROM "guilds" WHERE "guilds"."short_name" = 'ICPT' LIMIT 1
=> #<Guild id: 2, name: "Inception", detail: "Inception Guild", game_server_id: 2, created_at: "2011-10-30 17:41:19", updated_at: "2011-10-30 17:41:19", short_name: "ICPT">
ruby-1.9.2-p0 > guild.name.capitalize
=> "Inception"
More, if I put something like "puts #guild.inspect" right after the fetch, the capitalization works fine, hence I think it's lazy loading failure.
I'd be happy to have some idea as to how to solve that dumb problem ... I don't really want to have an #guild.inspect for nothing in my code, i find that to be lame solution ...
Thanks !
#PanayotisMatsinopoulos As requested, here is the table Guild :
create_table "guilds", :force => true do |t|
t.string "name"
t.text "detail"
t.integer "game_server_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "short_name"
end
#PanayotisMatsinopoulos Here you go my friend ;) I still have to i18n it
#encoding: utf-8
class Guild < ActiveRecord::Base
belongs_to :game_server
has_one :game, :through => :game_server
has_many :announcement, :dependent => :destroy
validates_presence_of :name, :on => :create, :message => "dois avoir un nom"
validates_presence_of :detail, :on => :create, :message => "dois avoir une description"
validates_presence_of :game, :on => :create, :message => "dois appartenir a un jeu"
validates_presence_of :short_name, :on => :create, :message => "dois avoir un acronyme"
validates_uniqueness_of :short_name, :on => :create, :message => "est deja utilise"
validates_length_of :short_name, :within => 3..5, :on => :create, :message => "dois faire entre 3 et 5 caracteres"
validates_exclusion_of :short_name, :in => %w( users admin guilds events loots sessions characters games password), :on => :create, :message => "ne peux pas utilisé se genre d'acronyme"
validates_uniqueness_of :name, :on => :create, :message => "est deja utilise"
has_many :guild_mates, :dependent => :destroy
has_many :guild_ranks, :dependent => :destroy
has_many :guild_settings, :dependent => :destroy
has_many :events, :dependent => :destroy
has_many :characters, :dependent => :destroy
before_validation :short_name_check ,:on => :create
after_create :guild_basic_settings
def guild_basic_settings
GuildSettingType.all.each do |grst|
grs = GuildSetting.create do |g|
g.guild_id = self.id
g.guild_setting_type_id = grst.id
g.value = "false"
end
end
set_setting(["setting_allow_basic_access_for_public","setting_allow_application",
"setting_allow_event_read_for_public","setting_allow_announcement_read_for_public"],"true")
end
def set_setting(setting,value)
if setting.class == Array
setting.uniq!
setting.each do |ar|
set_setting(ar,value)
end
else
grs = nil
if setting.class == String
grs = guild_settings.includes(:guild_setting_type).where(:guild_setting_type => {:name => setting}).first
return if grs.nil?
else
grs = guild_rank_settings.where(:guild_setting_type => setting)
return if grs.nil?
end
grs.value = value
grs.save
end
end
def short_name_check
short_name.upcase! if short_name
end
def full_name
"#{name.capitalize} - #{game_server.name}"
end
def characters_for_user(user)
characters.where(:user_id => user.id)
end
def method_missing(method,*args)
check = method.to_s.split("_")
if(args.count == 0)
if check[0] == "setting"
grs = guild_settings.joins(:guild_setting_type).where(:guild_setting => { :guild_setting_types => {:name => method.to_s}}).first
unless grs.nil?
return grs.value == "true" ? true : false
else
raise "Guild > Method Missing > unknown setting : #{method.to_s}"
end
end
end
end
end
Edit : I've just seen that i didn't super method missing ... might that be the problem ?
Okay it seems that the problem was my method_missing implementation. It was lacking super call ... Now that it has been restored, everything works fine. no wonder.
Thanks #PanayotisMatsinopoulos for your help :) (also thanks a good night of sleep ;p )
you should check if name is nil also:
if #guild.nil? || #guild.name.nil?
True. method_missing should call super at the end. But, I am not convinced that your problem is there. It may be. It may not.
On the other hand, let me tell something that I believe has more chances to be your problem. This is the fact that you carry out your validation on presence of name only :on => :create. This means that an update of an object Guild that does not contain the name will pass validation and will be saved in the database without problem. Then your setup_guild will definitely throw the error:
undefined method `capitalize' for nil:NilClass
app/controllers/application_controller.rb:29:in `setup_guild'
i.e. the error this discussion started about.
Hence, my suggestion is to remove your :on => :create condition on the validation of name. (an BTW...I suggest that you remove it from all your validations unless you know what you are doing)
But then, I cannot prove that this was your problem in the first place. I am just putting here my advice, rather than my positive answer as a solution to your problem.

How to seed a Rails 3.1 app with scoped mass assignment

How does Rails 3.1 (RC4) and scoped mass assignment expect us to work with seeds.rb when loading a list of data.
For example. I normally have something like:
City.create([
{ :name => 'Chicago' },
{ :name => 'Copenhagen' },
...
])
Which creates over 100+ cities. this doesn't work anymore since the City model has a scoped mass assignment :as => :admin.
As far as I know, the .create() method does not allow us to throw in :as => :admin.
Only .new() and .update_attributes() allows us to do this with :as => :admin.
So doing something like (below) is cumbersome (especially for 100+ records):
city1 = City.new({ :name => 'Chicago' }, :as => :admin)
city1.save
city2 = City.new({ :name => 'Copenhagen' }, :as => :admin)
city2.save
Any thoughts on this?
You can do the following:
City.create([
{ :name => 'Chicago' },
{ :name => 'Copenhagen' },
...
], :without_protection => true)
This completely overrides the mass assignment protection - so be sure to only use this in say the seeds.

Embedded reference not saved

Under mongoid and rails 3 I have a collection of Users and a collection a Projects which embed many Relationships, the models are:
class User
include Mongoid::Document
field :name, :type => String
referenced_in :relationship, :inverse_of => :user
end
class Project
include Mongoid::Document
field :title, :type => String
embeds_many :relationships
end
class Relationship
include Mongoid::Document
field :type, :type => String
references_one :user
embedded_in :subject, :inverse_of => :relationships
end
My problem is that the referenced user of a relationship is never saved into the relationship. For example for following command only saves :type:
project1 = Project.new( :title => "project1", :relationships => [ {:type => "master", :user => "4d779568bcd7ac0899000002"} ] )
My goal is to have a project document similar to this:
{ "_id" : ObjectId("4d77a8b2bcd7ac08da00000f"), "title" : "project1", "relationships" : [
{
"type" : "master",
"user" : ObjectId("4d775effbcd7ac05a8000002"),
"_id" : ObjectId("4d77a8b2bcd7ac08da000010")
}
] }
The :user is never present, am I missing something here? Thanks a lot for your help!
Ted
So a couple things you might want to change:
1) Avoid the field name "type" as this is a rails magic column name used by single table inheritance. Maybe change them to user_type and relationship_type.
2) With Mongoid 2.0 and up you can use Active Model syntax like has_many and belongs_to instead of references. http://mongoid.org/docs/relations/referenced/1-n.html
3) For your create, instead of assigning user with a user ID, try assigning a user object.
project1 = Project.new( :title => "project1", :relationships => [ {:type => "master", :user => User.first} ] )
Or you could assign a user_id like so:
project1 = Project.new( :title => "project1", :relationships => [ {:type => "master", :user_id => "the_use_id_you_want_to_associate"} ] )
FYI, you don't have to specify the inverse_of in "referenced_in :relationship, :inverse_of => :user". Just "referenced_in :relationship" will do the trick.