我是一个RoR新手(v3.2.13),我正在构建一个新的网站/应用程序,它有很多登陆页面,分为6-8种不同的布局。布局在更改顺序中使用类似的元素,因此我使用partials和layout继承来适当地呈现每个页面。
我的问题是我的表单(位于每个页面的顶部)也不一致(例如,一个页面可能只有一个“名称”和“电子邮件”字段,另一个页面将包含一个额外的“电话”字段,第三个可能还包括“密码”,“地址”和“国家”字段等),并为每个页面构建不同的部分看起来像一个非常浪费的方法,干嘛明智,更不用说它是多么无效特别是因为我预计将来会有大量的新页面。
我已经彻底研究了表单概念,但还没有找到一个我认为足够好的解决方案,可能是因为我是一个新手。不幸的是,我没有任何代码要呈现,因为我一直等到我决定开始编码的最佳方法。
到目前为止,我想到的是在Haml中使用jQuery和条件,我理解它们都是天真的方法,而我将每个字段编码为自己的部分将被视为反模式(或者 - 不是Rails 3方式)。
是否有与此类设计问题相关的最佳做法?是否有任何我错过的在线/其他资源会让我指向正确的方向?
谢谢!
答案 0 :(得分:3)
我会通过构建包含所有元素的单个表单来解决这个问题,将其放在部分表单中,并将其包含在所有登录页面上。然后在每个登录页面的各个样式表中,隐藏您不想在该特定页面上使用的所有元素。
要解决验证的潜在问题(例如,您需要验证是否在请求时提供了密码),您可以创建一个配置文件(例如config/initializers/landing_forms.rb
),您可以在其中指定要在每个表单中包含哪些表单字段,然后从该文件生成适当的CSS,并在验证中使用它,即:
YourInitializer = {
foo: [:email, :password],
bar: [:email, :name, :address],
baz: [:name, :phone]
}.with_indifferent_access.freeze
<%= 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
/* 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 %>
希望这足以让你入门!
答案 1 :(得分:0)
这种结构怎么样?
# Controller
@fields = [:name, :country, :phone]
# View
@fields.each do |field|
render "form/" + field.to_s
end
# form/name.html.erb
<%= text_field(:name) %>