首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重构动态行为的Rails最佳实践

重构动态行为的Rails最佳实践
EN

Stack Overflow用户
提问于 2009-06-22 15:22:21
回答 3查看 1.3K关注 0票数 2

我已经开发了应急国家/地区选择下拉列表,并且我希望将此行为分解到一个地址模型中,这样我就不必在每次希望用户能够输入完整地址时复制动态行为(或多或少地在视图和控制器之间分开)。

基本上我试着把我的脚趾浸入更深的干燥中。但是我不确定在哪里嵌入行为。我是使用模型还是帮助器来构建必要的表单?最重要的是:我可以在哪里以及如何调用动态行为来更新状态列表?我是否需要一个地址控制器,或者这一切都可以在模型中完成?

换句话说,我现在得到的视图是这样的:

代码语言:javascript
复制
  # _refine.html.erb
      <tr>
        <td>
        <%= label_tag :dest_country, 'Country: ' %></td><td>
          <%= select_tag :dest_country, 
            options_for_select(Carmen::country_names 
                      << 'Select a country', 
                :selected => 'Select a country'), 
            {:include_blank => true,
            :id => 'country_select',                              
            :style => 'width: 180px',
            :onchange => remote_function(
              :url => {:action => 'update_state_select'},
              :with => "'country='+value")} %>
        </td>      
      </tr>
      <tr>
          <div id="state_select_div">
            <td><%= label_tag :dest_state, 'State: &nbsp&nbsp' %></td>
            <td><%= select_tag :dest_state, 
                        options_for_select(Carmen::states('US').collect{
                                |s| [s[0],s[0]]} << ['Select a state'], 
                                :selected => 'Select a state'), 
                                {:style => 'width: 180px'} %></td>
          </div>      
      </tr>

update方法在控制器中:

代码语言:javascript
复制
# search_controller.rb

def update_state_select
  # puts "Attempting to update states"
  states = []
  q = Carmen::states(Carmen::country_code(params[:country]))
  states = q unless q.nil? 
  render :update do |page|
    page.replace_html("state_select_div",
    :partial => "state_select",
    :locals => {:states => states }
  )
 end
end

最后,我得到了一个部分,其中包含适当的名称或空白文本字段:

代码语言:javascript
复制
# _state_select.html.erb
<% unless states.empty? or states.nil? %>
      <%= label_tag :dest_state, 'Select a state'  %>
 <br/> <%= select_tag :dest_state, 
                     options_for_select(states.collect{|s| [s[0],s[0]]}  
                         << ['Select a state'], 
                       :selected => 'Select a state'), 
                       {:style => 'width: 180px'} %>
 <% else %>
   <%= label_tag :dest_state, 'Please enter state/province' %><br />
   <%= text_field_tag :dest_state %>
<% end %>

现在,我想要做的是能够通过模型(比如person has_one : address )关联一个地址,并在用于创建新Person的表单中使用如下内容

代码语言:javascript
复制
 <%= label_tag :name, 'What's your name?' %>
 <%= text_field_tag :name %>
 <%= label_tag :address, 'Where do you live?' %>
 <%= address_fields_tag :address %>

它可以生成适当的下拉列表,动态地耦合在一起,其结果可以通过Person.address.country和Person.address.state访问。

提前感谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-06-24 17:02:08

让我首先确保我正确理解了代码;当用户更改国家/地区选择框时,会向服务器发出AJAX请求,然后服务器会返回一个脚本,该脚本会用正确的条目更新State框?

如果是这样,我会使用一种完全不同的策略。使用dest_country更改时触发的回调。让此回调向例如/countries/{COUNTRY}/states.json (或.xml)发出AJAX GET请求。当然,您需要为此设置一个路由和控制器。使用返回值填充dest_state

更新:至于分解用户界面代码,可以尝试使用partials和helper。http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials

票数 2
EN

Stack Overflow用户

发布于 2009-06-22 17:50:21

数据属于模型,表示属于模板(和帮助器)。也就是说,我将开始将数据与表示分离,并删除无用的代码。

代码语言:javascript
复制
states.collect{|s| [s[0],s[0]]}

AFAIK,则不需要执行此操作。您可以将其简化为

代码语言:javascript
复制
states.collect{|s| s[0]}

代码语言:javascript
复制
states.collect(&:first)

但最重要的是,您可以在Carmen类中提供一个自定义方法来获取正确格式的数据。

还可以使用prompt => "Select a State“选项简化以下代码,这样您既不需要追加新的数组项,也不需要手动选择名为"Select a State”的项。

代码语言:javascript
复制
options_for_select(Carmen::states('US').collect{
                                |s| [s[0],s[0]]} << ['Select a state'], 
                                :selected => 'Select a state'),

最后,您可能希望将复杂的辅助函数封装在对象中,以便更容易使用Test::Unit套件进行测试。查看this screencast

谈论控制器,改变

代码语言:javascript
复制
# puts "Attempting to update states"
states = []
q = Carmen::states(Carmen::country_code(params[:country]))
states = q unless q.nil? 

转到

代码语言:javascript
复制
# puts "Attempting to update states"
states = Carmen::states(Carmen::country_code(params[:country])) || []

当您只能调用一个方法时,请确保不要调用两个方法。变化

代码语言:javascript
复制
<% unless states.empty? or states.nil? %>

转到

代码语言:javascript
复制
<% unless states.blank? %>
票数 1
EN

Stack Overflow用户

发布于 2010-03-11 03:57:22

我用Carmen和jQuery写了一篇关于这方面的博文。代码是可重用的,因为它存在于my addresses视图的部分中。我通过表单中的地址“fields_for”标记使用它。你可以在这里阅读整个条目:http://eric.lubow.org/2009/ruby/rails/country-state-select-using-carmen-and-jquery/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1027812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档