why decorate decorated object
briu opened this issue · comments
Why already decorated object decorates every time on calling decorate
?
With this approach, we can lost context, for example
user = User.last
decorated_user = user.decorate(context: { test: 1 })
decorated_user.context
=> {:test=>1}
decorated_user.decorate.context
=> {}
Is it right behaviour?
What is the use case where you are calling decorate
twice, but expecting the context
to remain the same? That is, what is the need for calling decorate
the second time?
Draper works best if you decorate at the very last moment, ideally in the view. Decorating early in the controller lifecycle is not recommended and leads to a whole host of problems.
We are using cells.
For example UserCell
,
class UserCell
def full_name
user.full_name
end
def filtered_email
user.filtered_email
end
def show_in_header?
user.email.present? && user.show_everywhere?
end
def user
object.decorate
end
end
class UserDecorator < Draper::Decorator
def full_name
"#{object.name} #{object.surname}"
end
def filtered_email
"#{object.email}[0..5]"
end
def show_everywhere?
context[:online]
end
end
Inside cell object many times calling decorator methods, and we decorate object inside.
Should object been decorated, before initializing cell?
This cell initializes many times, in different places.
Both cells and Draper are designed to solve similar problems (i.e. alternatives to view helpers). I have never seen them used in conjunction, so that's pretty interesting. I think your problem will go away if you change your user
method to:
def user
@user ||= object.decorate
end
This is a common pattern in Ruby to prevent re-initialization or creation of objects. Let me know if this solves your problem.
We firstly decorate collection with context, and secondly inside cell
The problem could be solved with this
cell(user.decorated? ? user : user.decorate)
And with usage object
instead user
inside cell
.
But cell always need decorated object, and decorating object inside cell is obvious for me.
So, object.decorate
- default, and decorate with context is how option
I'm not sure I followed that last sentence, but it sounds like you have a solution for this. Also, if you are decorating the collection beforehand, I don't think you will need to call decorate
when passing it into the cell. For instance:
<% @users.decorate(context: { test: 1 }).each do |user| %>
<%= cell(user) %>
<% end %>
But long story short, I believe this is the intended / expected behavior when calling decorate
again. Let me know if I can help with anything else.