0

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

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

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

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

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

谢谢!

4

2 回答 2

3

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

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

登陆表格.rb

YourInitializer = {
  foo: [:email, :password],
  bar: [:email, :name, :address],
  baz: [:name, :phone]
}.with_indifferent_access.freeze

_form.html.erb

<%= form_for ... do |f| %>
  <%= f.hidden_field_tag :landing_page_id, value: 'foobar' %>
<% end %>

控制器

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

page_forms.css.erb

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

希望这足以让你开始!

于 2013-08-20T18:20:14.453 回答
0

这种结构怎么样?

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

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

# form/name.html.erb
<%= text_field(:name) %>
于 2013-08-20T18:20:30.893 回答