0

I am working on Ruby on Rails, and I want to create a helper method for my view. I must pass an active record object, a symbol variable and a title to the method.

The objective of this method is to take the data, create some < strong > and < p > tags to put the title and the object attribute on the database (by accessing with the symbol variable) and get a nice HTML bit of code to put on my view.

Everything works fine, except when I need to display some of the object's attribute (like a datetime attribute, or a boolean value) which I need to call a specific object's method. For example, get the status of the user If he has confirmed his email, return string "Confirmed", if not, return string "Unconfirmed".

  • Helper code
module UsersHelper
    def user_show_field(user, column, title=nil)
        title ||= column.titleize
        return "<p><strong>#{title}</strong>: #{user[column]}</p>".html_safe
    end
end
  • View code
<%= user_show_field(@user, :city, "City") %>

In the example above, there will be no problem, because :city is a attribute from the user. So the helper method will attempt to make the call

@user[:city]

However, if I want to get the status of my user, I'll need to call the get_status method of my user:

@user[:get_status]

This Will return nil, because :get_status is not a attribute on the database of my user model: it is a method defined on my app/models/user.rb

class User < ApplicationRecord
    def get_status
        return registered ? "Email confirmed" : "Unconfirmed user"
    end

end

How can I add some code to my user model, so I can use the helper with both the attributes on the database or model's method?

Karl
  • 374
  • 1
  • 5
  • 15

2 Answers2

1

You can invoke methods with a symbol or a string using send (note that you can even call private methods with send, you can use public_send instead).

@user.send(:get_status)

If your method requires parameters, just add the separated by comma:

@user.send(:another_method, param1, param2)

https://ruby-doc.org/core-2.1.0/Object.html#method-i-public_send

arieljuod
  • 15,460
  • 2
  • 25
  • 36
  • Thanks, this has got the job done. How it is called this way of calling methods on ruby? To search more on google? lambda methods? – Karl Jan 31 '19 at 01:21
  • 1
    Ruby 1.9.3 is ancient and APIDock has been abandoned, you'd be better off linking to https://ruby-doc.org – mu is too short Jan 31 '19 at 01:28
  • 1
    @Karl, you can read about reflection and meta programming, check this example on wikipedia https://en.wikipedia.org/wiki/Reflection_(computer_programming)#Ruby – arieljuod Jan 31 '19 at 01:34
1

I would like to suggest instead of send all field, using one string is more simple, something like this below

module UsersHelper
  def user_show_field(user_data, title=nil)
      title ||= column.titleize
      return "<p><strong>#{title}</strong>: #{user_data}</p>".html_safe
  end
end

here you can call from your view, without change your model

   <%= user_show_field(@user.city, "City") %>
   <%= user_show_field(@user.get_status, "Status") %>
widjajayd
  • 6,090
  • 4
  • 30
  • 41
  • 1
    Sometimes simple is better than complex, thanks. However, I've always had some curiosity about how to get these kind of things done: I've always look at the models and the "before_validation :get_status" kind of thing, and I was wondering how to implement it.This was the opportunity to learn it. – Karl Jan 31 '19 at 01:25