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
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"
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?
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 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.
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.