Reputation: 737
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.
Upvotes: 0
Views: 841
Reputation: 27374
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?
Upvotes: 2