Ruby on rails 创建跨越多个不同布局的模块化表单的最佳实践

Ruby on rails 创建跨越多个不同布局的模块化表单的最佳实践,ruby-on-rails,ruby,forms,ruby-on-rails-3.2,partials,Ruby On Rails,Ruby,Forms,Ruby On Rails 3.2,Partials,我是一个RoR新手(v3.2.13),我正在构建一个新的站点/应用程序,它有很多登录页,分为6-8种不同的布局。布局使用的是变化顺序中的类似元素,因此我使用部分和布局继承来适当地呈现每个页面 我的问题是,我的表单(位于每页顶部)也不一致(例如,一个页面可能只有“姓名”和“电子邮件”字段,另一个页面将包含额外的“电话”字段,第三个页面可能还包括“密码”、“地址”和“国家”字段等),为每个页面构建一个不同的部分似乎是一个非常浪费的方法,干巴巴的,更不用说它是多么的无效,特别是因为我预计未来会有大量的

我是一个RoR新手(v3.2.13),我正在构建一个新的站点/应用程序,它有很多登录页,分为6-8种不同的布局。布局使用的是变化顺序中的类似元素,因此我使用部分和布局继承来适当地呈现每个页面

我的问题是,我的表单(位于每页顶部)也不一致(例如,一个页面可能只有“姓名”和“电子邮件”字段,另一个页面将包含额外的“电话”字段,第三个页面可能还包括“密码”、“地址”和“国家”字段等),为每个页面构建一个不同的部分似乎是一个非常浪费的方法,干巴巴的,更不用说它是多么的无效,特别是因为我预计未来会有大量的新页面

我已经彻底研究了表单的概念,但还没有找到一个我认为足够好的解决方案,可能是因为我是一个新手。不幸的是,我没有任何代码可以展示,因为我一直等到我决定开始编码的最佳方法

到目前为止,我想到的是在Haml中使用jQuery和条件语句,我知道这两种方法都很幼稚,而我读到将每个字段编码为其自己的部分将被视为反模式(或者,不是Rails 3方式)

是否有与此类设计问题相关的最佳实践?是否有我错过的任何在线/其他资源可以为我指明正确的方向


谢谢

我将通过构建一个包含所有元素的单一表单来解决这个问题,将其放在部分表单中,并将其包含在所有登录页上。然后在每个登录页的各个样式表中,隐藏您不想在该特定页上使用的所有元素

要解决验证中的潜在问题(例如,您需要验证在请求时是否提供了密码),您可以创建一个配置文件(例如,
config/initializers/landing_forms.rb
),其中您可以指定每个文件中包含哪些表单字段,然后从该文件生成适当的CSS,并在验证中使用它,即:

登陆表格.rb _form.html.erb

控制器
class UsersController
模型
class用户
page_forms.css.erb
/*默认情况下隐藏所有非按钮输入,然后单独显示*/
#形式。{显示:块}

希望这足以让你开始

我将通过构建一个包含所有元素的单一表单来解决这个问题,将其放在部分表单中,并将其包含在所有登录页上。然后在每个登录页的各个样式表中,隐藏您不想在该特定页上使用的所有元素

要解决验证中的潜在问题(例如,您需要验证在请求时是否提供了密码),您可以创建一个配置文件(例如,
config/initializers/landing_forms.rb
),其中您可以指定每个文件中包含哪些表单字段,然后从该文件生成适当的CSS,并在验证中使用它,即:

登陆表格.rb _form.html.erb

控制器
class UsersController
模型
class用户
page_forms.css.erb
/*默认情况下隐藏所有非按钮输入,然后单独显示*/
#形式。{显示:块}

希望这足以让你开始

这种结构怎么样

# Controller
@fields = [:name, :country, :phone]

# View
@fields.each do |field|
   render "form/" + field.to_s
end

# form/name.html.erb
<%= text_field(:name) %>
#控制器
@字段=[:姓名,:国家,:电话]
#看法
@字段。每个do |字段|
将“form/”+field.to_
结束
#form/name.html.erb

这种结构怎么样

# Controller
@fields = [:name, :country, :phone]

# View
@fields.each do |field|
   render "form/" + field.to_s
end

# form/name.html.erb
<%= text_field(:name) %>
#控制器
@字段=[:姓名,:国家,:电话]
#看法
@字段。每个do |字段|
将“form/”+field.to_
结束
#form/name.html.erb

最后,您能否提供一点您想要做的事情的背景信息?您的设计应该尽可能最好地反映您的意图,因此,如果这些是登录页的各种排列,那么共享部分代码的解决方案是有意义的;相反,如果它们有8个页面,目标完全不同(一个注册一份时事通讯,另一个注册Facebook,等等),那么你并没有像使用它那样复制代码,也没有一个共享的祖先(尽管抽象的表单生成器可能仍然合适)。@coreyward,感谢您的询问:将会有一个共享的祖先,也就是说,正如您所提到的,它们都是相同通用登录页的各种排列(它们都共享相同的页脚、页眉和逻辑)。为了回答您的问题,所有表单都有一个共同的目标,那就是将用户的详细信息发送给DB,以便将来进行通信。没什么好奇怪的。你能给我一点关于你最终要做什么的背景吗?你的设计应该重新设计
class UsersController < ApplicationController
  def create
    @user = User.new(params[:user])
    User.validate_only requested_fields
    # ...
  end
protected
  def requested_fields
    YourConfig.fetch params[:landing_page_id]
  end
end
class User < ActiveRecord::Base
  attr_reader :required_validations
  validate :email, presence: true, if: :email_required?

  def email_required? # feel free to use a bit of metaprogramming to make this simpler
    required_validations.include? :email
  end

  def validate_only(fields)
    @required_validations = fields
  end
end
/* Hide all non-button inputs by default, then show individually */
<% YourConfig.each_pair do |landing_page_id, fields| %>
  <% fields.each do |field| %>
    #<%= landing_page_id %> form .<% field %> { display: block }
  <% end %>
<% end %>
# Controller
@fields = [:name, :country, :phone]

# View
@fields.each do |field|
   render "form/" + field.to_s
end

# form/name.html.erb
<%= text_field(:name) %>