6

I found this in Ryan Bates' railscast site, but not sure how it works.

#models/comment.rb
def req=(request)
    self.user_ip    = request.remote_ip
    self.user_agent = request.env['HTTP_USER_AGENT']
    self.referrer   = request.env['HTTP_REFERER']
end

#blogs_controller.rb
def create
    @blog = Blog.new(params[:blog])
    @blog.req = request
    if @blog.save
        ...

I see he is saving the user ip, user agent and referrer, but am confused with the req=(request) line.

BryanH
  • 5,826
  • 3
  • 34
  • 47
sent-hil
  • 18,635
  • 16
  • 56
  • 74

3 Answers3

6

That line defines a method called req=. The = character in the end makes it an assignment method.

This is a regular setter method:

def foo(para1)
  @foo = para1
end

The setter method can be re-written as an assignment method as follows:

def foo=(para1)
  @foo = para1
end

Difference between the two setter methods is in the invocation syntax.

Assignment setter:

a.foo=("bar")   #valid syntax
a.foo= ("bar")  #valid syntax
a.foo = ("bar") #valid syntax
a.foo= "bar"    #valid syntax
a.foo = "bar"   #valid syntax

Regular setter:

a.foo("bar")    #valid syntax
a.foo ("bar")   #valid syntax
a.fo o ("bar")  #invalid syntax
Harish Shetty
  • 64,083
  • 21
  • 152
  • 198
6

To build on Karmen Blake's answer and KandadaBoggu's answer, the first method definition makes it so when this line is executed:

@blog.req = request

It's like doing this instead:

@blog.user_ip    = request.remote_ip
@blog.user_agent = request.env['HTTP_USER_AGENT']
@blog.referrer   = request.env['HTTP_REFERER']

It basically sets up a shortcut. It looks like you're just assigning a variable's value, but you're actually calling a method named req=, and the request object is the first (and only) parameter.

This works because, in Ruby, functions can be used with or without parentheses.

Community
  • 1
  • 1
Christopher Parker
  • 4,541
  • 2
  • 28
  • 33
  • Thanks for your answer. But the user_ip, user_agent, referrer are part of comments db table, just like comment.title, comment.body etc/ so why use @blog.user_ip? – sent-hil Apr 16 '10 at 05:59
2
def name=(new_name)
 @name = new_name
end

has the same functionality as:

def name(new_name)
 @name = new_name
end

However, when calling the methods you get a little nicer more natural looking statement using an assignment rather than argument passing.

person = Person.new
person.name = "John Doe"

vs.

person.name("John Doe")

Hope that helps.

Karmen Blake
  • 3,454
  • 3
  • 18
  • 9