Reputation: 4580
How can I add variables to an existing obejct? I have a list of chat rooms and I want to add a new variable for each chat to use at my view:
Example I want to add total users of chat
def index
chats_all = ChatRoom.all
@chats = Array.new
chats_all.each |chat|
chat.total_users = 10
@chats << chat
end
@chats
end
total_users is not an attribute of ChatRoom class.
[EDIT - explaim better after @jvillian great awnser]
I don't want total_users as an attribute of User class.
I just want to add as a variable to use at this one single page. For json rails already let my add new attributes to objects. Just need to use as_json().map and a merge()
Example:
def index
chats = chats.as_json().map {
|chat|
chat.merge(
total_users: 10
}
response = { chats: chats }
render json: response
end
Now I got an json with chats and each chat has total_users attribute.
I want to know if I can do something like this with objects, just add a temporary variable to use at index page.
Upvotes: 0
Views: 1128
Reputation: 4580
To create temporary custom Objects without add new attributes to database Struct solve my problem.
I can create a Struct with chat room info and total users
chat_info = Struct.new(:name, :total_users, :messages)
chat_temp = []
chats = ChatRoom.where(condition)
chats.each do |chat|
chat_temp << chat_info.new("nome", 100, messages)
end
Upvotes: 0
Reputation: 20263
Try
class ChatRoom < ActiveRecord::Base
attr_accessor :total_users
end
You can read more in the docs.
Then, index could look like:
def index
@chats = ChatRoom.all.map do |chat|
chat.total_users = 10
chat
end
end
Alternatively, I would be tempted to do something like:
class ChatRoom < ActiveRecord::Base
TOTAL_USERS = 10
attr_accessor :total_users
def total_users
@total_users || TOTAL_USERS
end
end
And then:
def index
@chats = ChatRoom.all
end
Now, you'll get
@chats.first.total_users
=> 10
You can set total_users
to something else if you like, but it will default to 10.
Here's a potential approach using OpenStruct:
def index
@chats = ChatRoom.all.map do |chat|
OpenStruct.new(
chat.
attributes.
merge!(total_users: 10)
)
end
end
Now, you can do:
@chats.each do |chat|
puts chat.total_users
end
which will return 10
.
BTW and TBH, I do something like that last sort of thing (using OpenStruct or custom decorators) all the time. In my more recent apps, views never have direct access to models.
Upvotes: 2
Reputation: 11193
Maybe you want to send the response to the view as an array and scan to show informations?
def index
@chats = ChatRoom.all.as_json().map { |chat| chat.merge("total_users" => 10) }
end
Then access @chats
, which is actually an array of hashes, view:
<% @chats.each do |chat| %>
<p><%= chat["total_users"] %></p>
<% end %>
You can check how @chats
is structured by <p><%= @chats %></p>
I maybe made some syntax error.
Upvotes: 0