Rendering rails partial with dynamic variables

2019-08-24 15:45发布

问题:

I'm trying to render a partial based on the taxon the user is inside. In my application.html.erb layout I have the following line of code:

<%= render 'spree/shared/women_subnav' if @enable_women %>

In the taxons controller, inside the show method, I have:

@taxon_id = params[:id].split('/').first

And in taxons#show I have:

<% if @taxon_id == params[:id].split('/').first %>
  <%= "@enable_#{@taxon_id}" = true %>
<% end %>

When I run this I get a SyntaxError. But in taxons#show If I just enter:

<% if @taxon_id == params[:id].split('/').first %>
  <%= "@enable_#{@taxon_id}" %>
<% end %>

without the '= true' then the page renders, outputting '@enable_women'. So I know it's getting the correct variable, I just need that variable to be set to true. What am I missing?

Thanks so much.

回答1:

use instance_variable_set

instance_variable_set "@enable_#{@taxon_id}", true

just a reminder that it's better to do these things inside a controller.



回答2:

First of all I would like to give you some heads-up:

  • calling first on a user submittable input is not a great idea (what if I submit ?id=, it would return nil) also non utf-8 encoding will crash your app such as: ?id=Ж

  • Controllers are beast! I see you are setting the value of a true/false instance_variable in the view, please use controllers do define the logic before rendering its output. especially when parameter dependant.

so for a solution: in your controller as params[:id] should suggest an INT(11) value:

def action
  # returning a Taxon should be a good idea here
  @taxon = Taxon.find(params[:id])
  # as I would give a Taxon class an has_many relation to a User
  @users = @taxon.users
end

and in your action's view

<%= render :partial => "taxons/users", collection: @users %>

of course you would have the great ability to scope the users returned and render the wanted partial accordingly.

if you want more info about "The Rails way" please read: http://guides.rubyonrails.org/

Have fun!