这是我的控制器:
def sedomain
@domain = params[:domain]
@virksomhed = Virksomhed.find(:all)
end
Virksomhed has_one Domain and Domain belongs_to Virksomhed。
我想要实现的是基于参数循环遍历域表中的所有行。
以下是dk域页面的示例。它工作正常。
<% @virksomhed.each do |virk| %>
<tr>
<td><%= virk.navn %></td>
<td><%= virk.domain.dk %> kr.</td>
<td><%= virk.domain.dkf %></td>
<td><%= virk.domain.dko %></td>
</tr>
<% end %>
但后来我想让它充满活力:
<% @virksomhed.each do |virk| %>
<tr>
<td><%= virk.navn %></td>
<td><%= virk.domain.@domain %> kr.</td>
<td><%= virk.domain.@domain %></td>
<td><%= virk.domain.@domain %></td>
</tr>
<% end %>
但是我收到语法错误。我也认为这是一个糟糕的解决方案,因为用户可以通过参数访问Domain表中的其他列。
答案 0 :(得分:2)
你不能取消引用这样的变量。你的意思是使用send
:
<td><%= virk.domain.send(@domain) %> kr.</td>
您需要确保此用户参数符合“已知良好”列表。有两种方法可以做到这一点,如果它无效,则预过滤和抛出错误,或者如果不符合则有一个方法可以安静地吃掉调用。
例如:
@domain =
case(params[:domain])
when 'dk', 'dku', '...'
params[:domain]
else
raise "Hey, what are you doing?"
end
答案 1 :(得分:0)
require 'set'
DOMAINS = Set.new( %W{dk dkf dko} )
据我了解,您的params[:domain]
可以是数组或字符串。要检查域是否已列入白名单,您可以执行以下操作:
# ...
@domains= check_domains( params[:domain] )
# ...
def check_domains( dom )
case dom
when Array
dom if dom.to_set.subset?( DOMAINS )
else
[dom] if DOMAINS.include?( dom )
end
dom ||= []
end
然后在你的视图中(或者作为一些助手/部分):
<% if @domains.any? %>
<% @domains.each do |domain| %>
<td><%= virk.domain.send(domain) %> kr.</td>
<% end %>
<% end %>