基于model动态地ComboBox为生成options

本文介绍了一种在Ruby on Rails中简化ComboBox创建的方法。利用RoR提供的helper方法结合动态语言特性,通过定义通用函数get_select_options_for简化了基于不同model创建ComboBox的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在使用RoR创建form时,很多时候需要基于model之间的关系创建ComboBox。RoR提供了很多方便的helper方法帮助我们完成一个 form的创建。例如,如果想要为article创建一个form,并且要为article选择category时,可以使用如下方法:

<% form_for(:material, :url => url, :html => { :method => method }) do |f| %>
<p><label>Name</label><br/>
<%= f.text_field :name %></p>
<p><label>Category</label><br/>
<%= f.select :category_id, get_category_select_options %></p>
<p><label>Content</label><br/>
<%= f.text_area :content %></p>
<p><%= submit_tag 'Create' %></p>
<% end %>

而其中的get_category_select_options可以采用如下实现方式(定义在articles_helper中):

def get_category_select_options
Category.find(:all, :order => 'name').collect { |item| [item.name, item.id] }.insert(0, ['Please select...', nil])
end

以上代码通过Category类找到所有的category,然后使用其中的name和id属性(注意顺序)作为options的label和data,最后在加入一个默认的选项“Please select...”。一切都很简单,不是吗?

然而,如果model之间的关联稍微复杂一点儿,就可能会在很多地方使用类似的方法获得ComboBox的选项,那么为每个可能成为ComboBox选项的model都写这么一个方法实在是太麻烦了。如果是在Java世界中,我们可以很快想到使用反射来解决这个问题。也就是说在知道类名的情况下,用 Class.forName得到Class对象,然后在调用其上的find方法之类的。但是我们使用的是Ruby这个号称动态能力超强的语言,有什么更容易的做法吗?当然,代码如下:

def get_select_options_for(symbol)
Object.const_get(symbol.to_s.capitalize).find(:all, :order => 'name').collect { |item| [item.name, item.id] }.insert(0, ['Please select...', nil])
end

关键就在这个const_get方法上,它是Module的一个静态方法,所以我们可以通过Object来调用它。我们把类名传递进去,它就可以返回这个类。但是注意这里的写法,我们可以在返回类上直接调用find,而不是像Java那样clazz.getMethod(...).invoke (...),是不是非常的方便呢?我们可以把这个方法定义在application_helper中,这样在所有的view中就都可以使用了,那么上面的 form代码就变成了如下这样:

<% form_for(:material, :url => url, :html => { :method => method }) do |f| %>
<p><label>Name</label><br/>
<%= f.text_field :name %></p>
<p><label>Category</label><br/>
<%= f.select :category_id, get_select_options_for(:category) %></p>
<p><label>Content</label><br/>
<%= f.text_area :content %></p>
<p><%= submit_tag 'Create' %></p>
<% end %>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值