Forum: Ruby What does this code do?

Posted by Mike Glaz (mikeglaz)
on 2012-07-16 04:19
I'm reading through a tutorial and found a solution for it (because I'm
stuck), but I don't understand some code, so I was hoping someone could
shed some light on it:

USERNAME_REGEX = /@\w+/i

class Micropost < ActiveRecord::Base
    def people_replied
      users = []
      self.content.clone.gsub!( USERNAME_REGEX ).each do |username|
        user = User.find_by_username(username[1..-1])
        users << user if user
      end
      users
    end
end

This is a blog/twitter like app and I'm guessing self.content should
contain  a string like '@mike hi how are you?'.  What would be the
result in the users array with such a string?

The class User looks like so:

class User < ActiveRecord::Base
  attr_accessor :password
  attr_accessible :name, :email, :password, :password_confirmation,
:username

  has_many :microposts, :dependent => :destroy
end
Posted by Sam Duncan (Guest)
on 2012-07-16 04:32
(Received via mailing list)
On 07/16/2012 02:19 PM, Mike Glaz wrote:
>          user = User.find_by_username(username[1..-1])
> The class User looks like so:
>
> class User<  ActiveRecord::Base
>    attr_accessor :password
>    attr_accessible :name, :email, :password, :password_confirmation,
> :username
>
>    has_many :microposts, :dependent =>  :destroy
> end

Without knowing much about ActiveRecord, I would imagine your users
array to contain an instance of class User for each person who had a
record whereby their 'username' matched a '@<username>' fragment from
your Micropost instances content. In other words; if the content
contained '@mike', then your users array would contain a User instance
with the username attribute of 'mike'. Does that match what you see? If
this is a 'Rails' app you could probably get additional help from the
Rails mailing list.

Hope that helps.

Sam
Posted by Mike Glaz (mikeglaz)
on 2012-07-16 04:39
Ok, thanx, I'll repost there.
Posted by Ryan Davis (Guest)
on 2012-07-16 22:25
(Received via mailing list)
On Jul 15, 2012, at 19:19 , Mike Glaz wrote:

>        user = User.find_by_username(username[1..-1])
>        users << user if user
>      end
>      users
>    end
> end

This code is _so_ bad that I'd stop reading this tutorial and go read 
some other tutorial. It'd bad enough that it shouldn't be explained as 
it currently stands, honestly. Instead, I can show you how it (probably) 
should have been written:

class Micropost < ActiveRecord::Base
  def people_replied
    content.scan(/@\w+/).map { |name| User.find_by_username name[1..-1] 
}.compact
  end
end
Posted by Lars Haugseth (Guest)
on 2012-07-17 12:53
(Received via mailing list)
On 07/16/2012 10:24 PM, Ryan Davis wrote:
>>     def people_replied
>>       users = []
>>       self.content.clone.gsub!( USERNAME_REGEX ).each do |username|
>>         user = User.find_by_username(username[1..-1])
>>         users << user if user
>>       end
>>       users
>>     end
>> end
>
> This code is _so_ bad that I'd stop reading this tutorial and go read
 > some other tutorial. It'd bad enough that it shouldn't be explained 
as
 > it currently stands, honestly.

Seconded.

> Instead, I can show you how it (probably)  should have been written:
>
> class Micropost < ActiveRecord::Base
>    def people_replied
>      content.scan(/@\w+/).map { |name| User.find_by_username name[1..-1] 
}.compact
>    end
> end

How about:

   def people_replied
     User.where :username => content.scan(/@(\w+)/)
   end
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.