For some reason I am tripping up on the use of self and new.
class LineItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
def self.from_cart_item(cart_item)
li = self.new
li.product = cart_item.product
li.quantity = cart_item.quantity
li.total_price = cart_item.price
li
end
end
new is used to create a new object.
A new object is often created by using the class name followed by .new
e.g People.new, Items.new etc.
However in the example you gave you are creating a new object from
within the class, i.e. you are creating a LineItem object from within
the LineItem class and so instead of saying LineItem.new you use the
self keyword and it creates the object.
I don’t know for sure because I haven’t encountered a situation where
I’d
need to do things like this… But I’ll give it a shot - I’m open to
corrections…
class LineItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
def self.from_cart_item(cart_item)
li = new
li.product = cart_item.product
li.quantity = cart_item.quantity
li.total_price = cart_item.price
return li
end
end
You’d simply use the new method without the self because self is used to
refer to the current instance of the object. Also, you should put return
li
at the end; you don’t have to, but it just makes the code easier to
read.
On Wed, May 5, 2010 at 3:21 PM, dev [email protected] wrote:
li.total_price = cart_item.price
.
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.
–
Joshua S. Martin
CONFIDENTIALITY NOTE: This e-mail message, including any attachment(s),
contains information that may be confidential, protected by the attorney
client or other legal privileges, and or proprietary non public
information.
If you are not an intended recipient of this message or an authorized
assistant to an intended recipient, please notify the sender by replying
to
this message and then delete it from your system. Use, dissemination,
distribution, or reproduction of this message and or any of its
attachments
(if any) by unintended recipients is not authorized and may be unlawful.
dev wrote:
For some reason I am tripping up on the use of self and new.
class LineItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
def self.from_cart_item(cart_item)
li = self.new
li.product = cart_item.product
li.quantity = cart_item.quantity
li.total_price = cart_item.price
li
end
end
This all looks correct. What problem do you think you’re having? Which
tests are failing?
More importantly, why do you think you need to do this in the first
place? Although the method seems correct, it also seems like a strange
thing for your app to need.
Best,
Marnen Laibow-Koser
http://www.marnen.org
[email protected]
dev wrote:
For some reason I am tripping up on the use of self and new.
class LineItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
def self.from_cart_item(cart_item)
li = self.new
li.product = cart_item.product
li.quantity = cart_item.quantity
li.total_price = cart_item.price
li
end
end
This pattern looks very much like the NSCoding protocol pattern that I’m
familiar with from the Cocoa frameworks. Compare what you have with this
Objective-C example:
- (id)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
mapName = [[coder decodeObjectForKey:@“MVMapName”] retain];
legendView = [[coder decodeObjectForKey:@“MVLegend”] retain];
auxiliaryView = [coder decodeObjectForKey:@“MVAuxView”];
magnification = [coder decodeFloatForKey:@“MVMagnification”];
return self;
}
This implementation is slightly more abstract, and implemented as an
instance method rather than a class method, but it serves essentially
the same purpose.
To use this method you would do this:
id myObject = [[MyObject alloc] initWithCoder:coder];
Notice that Obj-C instance methods begin with a minus sign (-) and class
methods begin with a plus sign (+). Since this is an instance method the
instance must be allocated before being initialized. This alloc-init
process is roughly equivalent to Ruby’s “new” method.
One way to declare a class method in Ruby is to begin it with “self.”
Which is what you are doing in your code (self.from_cart_item). In order
to use class methods you send messages to the class rather than an
instance of the class:
my_line_item = LineItem.from_cart_item # LineItem class is the receiver
of message from_cart_item
On May 5, 2010, at 3:21 PM, dev wrote:
li.total_price = cart_item.price
li
end
end
While you already have some good answers from Joshua, Floyd, and
Marnen, I’ll add a bit to what they said from a Rails idiom perspective.
(Or ActiveRecord idiom if you prefer.)
class LineItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
def self.from_cart_item(cart_item)
new(:product => cart_item.product,
:quantity => cart_item.quantity,
:total_price => cart_item.price)
end
end
I think I recognize that example, so I suspect that you’re working
through the
Agile Wed Development with Rails. Like others have said, you could
have put
self.new since self is the default receiver of a method and from
within a
class method (i.e., defined on the LineItem class itself rather than
on an
instance of that class). This is just a specialized form of instance
creation
that knows how to create a new LineItem that has the properties from a
CartItem (which is presumably never in the database and thus not an
ActiveRecord model itself).
There are other ways of doing this same initialization, for example,
with a block passed to new:
class LineItem < ActiveRecord::Base
belongs_to :order
belongs_to :product
def self.from_cart_item(cart_item)
new do |li|
li.product = cart_item.product
li.quantity = cart_item.quantity
li.total_price = cart_item.price
end
end
end
You can think about LineItem.from_cart_item as a kind of cast or
constructor if you’re coming from C or Java (but please let it me just
a fleeting thought that never appears once you “get it” from a Ruby
perspective ;-).
-Rob
Rob B.
http://agileconsultingllc.com
[email protected]
[email protected]
I understand their position, but don’t you think it’s kinda weird to
just
leave it like that… No operations or anything… Ruby is all about
readability, and to just type the name of the object without performing
any
operations on it is not really natural. It’s like, what the heck is it
doing
just sitting there like that? Why even waste the time typing it at all
if it
doesn’t do anything?
Question: Doesn’t Ruby automatically return the object you were last
operating on? So, we could do whatever we want to the object we created,
and
just let it return the object automagically?
On Thu, May 6, 2010 at 2:37 PM, Joe S.
[email protected]wrote:
–
Joshua S. Martin
CONFIDENTIALITY NOTE: This e-mail message, including any attachment(s),
contains information that may be confidential, protected by the attorney
client or other legal privileges, and or proprietary non public
information.
If you are not an intended recipient of this message or an authorized
assistant to an intended recipient, please notify the sender by replying
to
this message and then delete it from your system. Use, dissemination,
distribution, or reproduction of this message and or any of its
attachments
(if any) by unintended recipients is not authorized and may be unlawful.
On 6 May 2010 22:11, Joshua M. [email protected] wrote:
Question: Doesn’t Ruby automatically return the object you were last
operating on?
not quite.
it returns the result of the last operation.
Joshua M. wrote:
Also, you should put return li at the end; you
don’t have to, but it just makes the code easier to read.
Oddly most ruby style guides I’ve seen disagree with this. They
recommend
using return only if one is returning from the middle of the function.
On Thu, May 6, 2010 at 5:15 PM, Michael P. [email protected]
wrote:
On 6 May 2010 22:11, Joshua M. [email protected] wrote:
Question: Doesn’t Ruby automatically return the object you were last
operating on?
not quite.
it returns the result of the last operation.
Actually the value of the last expression.
Which is why ending a method with a variable name doesn’t do nothing,
as Joshua seems to think, it provides the result of the method.
And it IS standard ruby practice.
–
Rick DeNatale
Blog: http://talklikeaduck.denhaven2.com/
Github: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
On 7 May 2010 01:19, Rick DeNatale [email protected] wrote:
On Thu, May 6, 2010 at 5:15 PM, Michael P. [email protected] wrote:
it returns the result of the last operation.
Actually the value of the last expression.
Sorry; of course, expressions can be comprised of several operations