如何在变量名中添加数据,Ruby?

1yjd4xko  于 12个月前  发布在  Ruby
关注(0)|答案(3)|浏览(96)

所以我得

LanRole.where("lan_id = ?", requestable.id).each do |lan_role| %>
    <% @lan_??? = Lan.find(lan_role.lan_id) %>
    <li><a data-toggle="tab" href="#lan_info_<%= lan.id %>"><%= lan.name %> INFO</a></li>

其中???应该是lan_role.id,以便稍后将其放入选项卡中

<div class="tab-content">
  <div id="lan_info_<%= lan.id %>" class="tab-pane fade">
    <h4><%= @lan_???.name %> INFO</h4>
    etc
  </div>

但我不知道如何使变量变量名,它在那里。
如果是一根绳子,我可以

#{lan_role.id}

但它不是一根弦
.我看错了错误,它在<div id="lan_info_<%= lan.id %>" class="tab-pane fade">

ActionView::Template::Error (undefined local variable or method `lan' for #<#<Class:0x007f7afb9e98a0>:0x007f7afb28aeb0>):
3duebb1j

3duebb1j1#

对于“可变”变量:

{one: 1, two: 2, three: 3}.each do |name, id|
  instance_variable_set("@lan_#{name}", [id, name])
  p @lan_one, @lan_two, @lan_three
end

[1, :one]
nil
nil
[1, :one]
[2, :two]
nil
[1, :one]
[2, :two]
[3, :three]

但是因为你是在制作制表符,所以只需要两个循环,一个用于链接,一个用于主体:

collection = LanRole.where("lan_id = ?", requestable.id)

# make tabs
collection.each do |role|
  role.name
end

# make tab contents
# collection is now loaded it won't hit the database again, at least it shouldn't
collection.each do |role|
  role.description
end
du7egjpx

du7egjpx2#

你可以使用instance_variable_setinstance_variable_get来实现,如下所示:

<% LanRole.where("lan_id = ?", requestable.id).each do |lan_role| %>
    <% instance_variable_set(:"@lan_#{lan_role.lan_id}", Lan.find(lan_role.lan_id)) %>
<% end %>

然后当你试图把它弄出来时,用途:

<h4><%= instance_variable_get(:"@lan_#{lan_role.lan_id}").name %> INFO</h4>
biswetbf

biswetbf3#

可以使用instance_variable_setinstance_variable_get来设置和获取具有动态名称的示例变量,但这很麻烦。除非你在做元编程(特别是在你的例子中),否则我会把使用这些方法称为代码气味。
相反,通过键存储数据的go to数据结构使用Hash。在您的示例中,利用Hash通过其id存储数据可能如下所示:

<% @lans_by_id = {} %>
<% LanRole.where("lan_id = ?", requestable.id).each do |lan_role| %>
  <% @lans_by_id[lan_role.lan_id] = Lan.find(lan_role.lan_id) %>
  # ...

你可以在代码后面类似地读取数据:

<h4><%= @lans_by_id[lan_role.lan_id].name %> INFO</h4>

**但是:**您使用Ruby on Rails标记了您的问题,并且LanRole的示例已经具有lan_id属性。因此,我建议您利用RubyonRails并在模型之间配置适当的Active Record Associations

当您像这样配置LanRoleLan之间的关联时:

# in app/models/lan_role.rb
class LanRole < ApplicationRecord
  belongs_to :lan
  # ... 

#in app/models/lan.rb
class LanRole < ApplicationRecord
  has_many :lan_roles # or just `has_one :lan_role`?

当你在模型中设置了这些关联时,你可以通过调用lan_role.lan而不是Lan.find(lan_role.lan_id)来获得给定lan_rolelan。为了避免在each迭代的每个块中加载一个lan,我建议立即用includes加载所有关联的lans
把所有的放在一起:加载和迭代

LanRole.where(lan_id: requestable.id).includes(:lan).each do |lan_role| %>

然后使用相关的lan,如下所示:

<h4><%= lan_role.lan.name %> INFO</h4>

相关问题