0

Is it possible in Ruby to instantiate another object of a different class using a class method?

I have spent a lot of time to no avail researching Google, the Ruby docs, and Stack Overflow, for an answer to my query, so I am posting this question as a last resort.

Two classes, User, and Blog. In User below I am trying to create a new instance of an object for Blog, and carry over some attributes.

In class User there are 2 methods;

class User
  attr_accessor :blogs, :username

  def initialize(username)
    self.username = username
    self.blogs = []
  end

  def add_blog(date, text)
    self.blogs << [Date.parse(date),text]
    new_blog = [Date.parse(date),text]
    Blog.new(@username,date,text)
  end
end

Using the above add_blog I would like to initialize & send a new object to the Blog class.

class Blog
  attr_accessor :text, :date, :user
  def initialize(user,date,text)
    user = user
    date = date
    text = text
  end
end
2
  • If instantiate a User object: harry = User.new("harry1") - puts harry.user results in: undefined method `user' for #<User:0x007fdc530c2f60> (NoMethodError) Commented Aug 23, 2015 at 16:13
  • harry is already the user, so you need to call 'puts harry.username' Commented Aug 23, 2015 at 16:20

2 Answers 2

1

Yes, it is possible to instantiate another object of a different class using a class method. We ruby programmers are doing it all the time.

Do you want to have the blogs attribute of the user to have an array of blogs? Because your code just puts a date-text tupel into the array.

I think you wanted to do something like this in your user class:

  def add_blog(date, text)
    parsed_date = Date.parse(date)
    new_blog = Blog.new(@username, parsed_date, text)
    self.blogs << new_blog
    new_blog 
  end

I have showed it step after step, but you can combine several lines. The last line returns the new blog, you may not need it if you only want the blog be part of the blogs array.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! these are both very useful solutions. But I was then expecting that I would be able to call this new object as an instance of Blog, as it has been created with Blog.new above, is this possible?
yes. it just depends on the last line, which tells ruby what you return in the method. In my implementation, the new Blog object is returned, and you can call other methods on it.
You can also access the blog via the user, like so: harry.blogs[0].text
1

Looks like your code has some flaws. Here is the corrected code: You were not using @ to assign values to instance variables, you were putting a date in @blogs, instead of Blog object.

If you want to pass instance of User to Blog from add_blog, you can use self which represents current instance of User class. If you want to carry just some attributes, then, you can do so by referring to attributes using @attribute_name or self.attribute_name syntax

require "date"
class User
  attr_accessor :blogs, :username

  def initialize(username)
    @username = username
    @blogs = []
  end

  def add_blog(date, text)
    @blogs << Blog.new(@username, Date.parse(date),text)
    self
  end

  def to_s
    "#{@username} - #{@blogs.collect { |b| b.to_s }}"
  end
end

class Blog
  attr_accessor :text, :date, :user

  def initialize(user,date,text)
    @user = user
    @date = date
    @text = text
  end

  def to_s
    "Blog of #{user}: #{@date} - #{@text}"
  end
end

puts User.new("Wand Maker").add_blog("2015-08-15", "Hello")
# => Wand Maker - ["Blog of Wand Maker: 2015-08-15 - Hello"]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.