基于参数的难度设置循环

时间:2011-11-04 18:18:54

标签: ruby-on-rails ruby ruby-on-rails-3

这是我的控制器:

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表中的其他列。

2 个答案:

答案 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)

@ tadman的答案很好,但我想补充两分钱。正如@Emily所说,您可以将列入白名单的域存储为常量:

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 %>