Problem when rendering partials dynamically

Asked

Viewed 162 times

1

I have the following code:

<table class="table table-bordered table-striped" border="0">
  <% @time_line.each do |time_line| %>
    <%= render partial: partial_name( get_type(time_line) ), locals: { register: time_line } %>
  <% end %>
</table>

@time_line is a variable that concatenates records from multiple models. To complicate matters, for each type of object, I need a different view (it’s a requirement of the project, I can’t change it). So, to make it easier to maintain later, I thought I’d do it this way up. The codes of the methods I used to try to dynamically call the partials:

def partial_name(class_name)
  partial_names = {
    "Custa" => 'financial',
    "Andamento" => 'course',
    "Movimentacaoweb" => 'web_movement',
    "Publicacao" => 'publication',
    "Audiencia" => 'hearing',
    "Anotacao" => 'anotation'
  }

  partial_names[class_name.to_s]
end

def get_type(obj)
 obj.class.to_s == 'Mensagem' ? obj.model.to_s : obj.class.to_s
end

For some reason, when I run, it gives the following error:

'nil' is not an Activemodel-compatible Object that Returns a Valid partial path.

Can anyone explain to me what I’m doing wrong?

  • 1

    this message occurs when running <%= render partial:... ? %> def partial_name is inside a helper?

  • Yes.... inside a helper.

2 answers

0

Dude I may be freaking out but are sure that @time_line is an instance variable?

If it really is, it always will be nil in your context because you are calling time_line instead of @time_line!! So to solve the problem just change this line:

<table class="table table-bordered table-striped" border="0">
  <% @time_line.each do |time_line| %>
    <%= render partial: partial_name( get_type(time_line) ), 
                        locals: { register: time_line } %>
  <% end %>
</table>

for:

<table class="table table-bordered table-striped" border="0">
  <% @time_line.each do |time_line| %>
    <%= render partial: partial_name(get_type(@time_line)), 
                        locals: { register: @time_line } %>
  <% end %>
</table>

UPDATE 02

I’ve been going over it again and I saw a possible problem: "your surrender statement". How about switching to:

<%= render partial_name(get_type(time_line)), locals: { register: time_line } %>

Valeuu!

  • @time_line is rather an instance variable... It doesn’t have with me to use the way you suggested because it contains an Activerecord object array. That’s why I used each. time_line represents the object corresponding to each iteration.

  • Beauty, I changed the answer, so remember always used without the hash with the key: partial! forehead the way I put it there, (I’m without the pc here to see if it works! :/ )

  • If that last answer doesn’t work, paste a debug of your object array there! :D

0

Rails knows how to find the partial of a model automatically.

http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials

If you have an instance of a model to render into a partial, you can use shorthand syntax:

<%= render @customer %>

Assuming that the @Customer instance variable contains an instance of the Customer model, this will use _Customer.html.erb to render it and will pass the local variable Customer into the partial which will refer to the @Customer instance variable in the Parent view.

So your code could be changed to:

<table class="table table-bordered table-striped" border="0">
  <% @time_line.each do |tl| %>
    <%= render tl, locals: { register: tl } %>
  <% end %>
</table>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.