ruby-on-rails - 无法循环通过 rails 哈希
问题描述
我正在开发一个遗留应用程序并且我正在重构设置,我们有一个奇怪的数据库结构,但由于现有数据而无法更改。
我遇到的问题如下,设置是使用 a 创建的db:seed
,这很好,但是,我无法进入表单并更新它们。
这是我到目前为止所拥有的(文件缩短了长度)
表单在索引上,所以我将所有内容移至该方法,并注释掉了所有遗留代码
控制器
class SettingsController < ApplicationController
load_and_authorize_resource
before_action :authenticate_user!
respond_to :json, :html
def index
# all_params_permitted
# strip_list = [
# 'company_main_mail',
# 'company_accounts_mail',
# 'company_web_site',
# 'company_vat_number'
# ]
# @errors = []
# @error_list = []
# @settings = params[:settings].each do |index, value|
# setting = Setting.find_by(name: index)
# if setting
# setting.value = value
# end
# setting.save
# end
# params[:settings].each do |index, value|
# setting = Setting.find_by(name: index)
# if setting
# if strip_list.include? setting.name
# setting.value = value.strip
# else
# setting.value = value
# end
# setting.save
# if setting.errors.present?
# @errors << setting
# @error_list << {name: setting.name , value: value}
# end
# end
# end
# check_boxes = [
# 'company_incorporation_status',
# 'company_vat_status',
# 'is_vso',
# 'is_efpm',
# 'exclude_non-manufactured_from_wo_creation_from_so',
# 'check_stock_levels',
# 'show_vat_on_uninvoiced_sales',
# 'hide_due_date_on_sales_quotes_and_orders',
# 'hide_due_date_on_purchase_quotes_and_orders',
# 'kpi_use_average_cos',
# 'kpi_use_average_labour',
# 'discounts_enabled',
# 'remove_works_order_from_plan_after_edit',
# 'user_change_own_password',
# 'auto_populate_receive_invoice',
# 'assume_supplier_has_vat_number_for_auto_populate_receive_invoice',
# 'enable_comments_on_stock_components',
# 'default_true_create_supply_orders',
# 'sales_order_item_custom_info_1_enabled',
# 'update_probability_on_opportunity_status_change',
# 'no_supplier_serial_numbers',
# 'enable_batch_number_generation',
# 'include_sales_order_notes_on_picking_lists',
# 'backorder_default',
# 'consolidate_work_order',
# 'over_delivery_default',
# 'restrict_purchase_invoice_query_flag',
# 'use_package_lines',
# 'hightlight_below_order_quantity_on_grn',
# 'show_poi_descriptions_on_order_lines',
# 'intrastat_enable',
# 'intrastat_enable_tod',
# 'api_enabled',
# 'wo_process_start_time',
# 'negative_current_stock',
# 'btp_enabled',
# 'enable_custom_documents',
# 'vat_adjustment_limit',
# 'cash_accounting',
# 'is_northern_ireland_protocol'
# ]
# check_boxes.each do |box|
# if !params[:settings][box]
# setting = Setting.find_by_name(box)
# if setting
# setting.value = 0
# setting.save
# end
# end
# end
# params[:large_settings].each do |index, value|
# setting = LargeSetting.find_by_name(index)
# if setting
# setting.value = value
# setting.save
# end
# end
# if params[:company_logo]
# @company_logo = Image.find_by_code('LOGO')
# @company_logo.update_attributes(params[:company_logo])
# end
# if params[:factoring_image]
# @factoring_image = Image.find_by_code('FACTORING')
# @factoring_image.update_attributes(params[:factoring_image])
# end
# if (@factoring_image && @factoring_image.errors && @factoring_image.errors.size > 0) || (@company_logo && @company_logo.errors && @company_logo.errors.size > 0) || (@errors.size > 0)
# @settings = get_settings(true)
# if @error_list.size > 0
# @error_list.each do |error|
# @settings[error[:name]] = error[:value]
# end
# end
# render settings_path
# else
# redirect_to settings_path
# end
end
private
def setting_params
params.require(:setting).permit(
:name,
:value,
:value_type
)
end
end
形式
<div class="l-12col" id="settings_form">
<%= form_for @settings, method: :post, multipart: true do |f| %>
<%# post_code %>
<div class="tabs">
<!-- start tab headings -->
<div class="tab-headings">
<a class="tab-button active" data-id="company_details">Company Details</a>
<a class="tab-button" data-id="tax_payroll">Tax & Payroll</a>
<a class="tab-button" data-id="system_settings">System Settings</a>
<a class="tab-button" data-id="trade_terms">Trade Terms</a>
<a class="tab-button" data-id="factoring">Factoring</a>
<a class="tab-button" data-id="document_storage">Document Storage</a>
<% if Features.API? %>
<a class="tab-button" data-id="web_api">Web API</a>
<% end %>
</div>
<!-- end tab headings -->
<div class="tab-contents">
<!-- start of company_details tab -->
<div class="tab-content active" id="company_details">
<div class="l-row-block clearfix">
<div class="l-06col l-ml-12col l-md-12col">
<h2 class="txt-title-alt">
Name & Address
<span data-tooltip title="Full legal name and address for this business as it should appear on business documentation.">
<span class="icon-help-with-circle" aria-hidden="true"></span>
</span>
</h2>
<div class='field l-margin-sm'>
<%= f.label :company_name %>
<%= f.text_field :company_name %>
</div>
<div class='field l-margin-sm'>
<%= f.label :company_system_display_name %>
<%= f.text_field :company_system_display_name %>
</div>
<div class='field l-margin-sm'>
<%= f.label :company_address_1, "Address Line 1" %>
<%= f.text_field :company_address_1 %>
</div>
...
</div>
</div>
</div>
<!-- end of company_details tab -->
...
</div>
</div>
<div class="btns">
<%= submit_tag "Update", id: 'company_settings_update_btn' %>
<%= link_to "Cancel", root_path, class: "btn-medium" %>
</div>
<% end %>
</div>
作为测试,这是我尝试过的。
我添加@settings = Setting.new
到索引中,然后给了我一个未定义的方法错误,所以在模型中我添加了以下内容
def company_name
Setting.find_by(name: :company_name).value
end
它使用正确的公司名称呈现页面,但是,有 135 个设置,所以我需要一种方法来保存所有这些设置。
解决方案
我建议您在模型上添加一个类方法:
def self.value_for(setting)
Setting.find_by(name: setting).try(:value)
end
value
并在您的字段上设置属性:
f.text_field :company_name, value: Setting.value_for(:company_name)
f.number_field :quote_value, value: Setting.value_for(:quote_value)
它并不完美,但非常清晰易读,这在遗留代码中很重要
在控制器中,类似的东西应该可以完成这项工作:
def update
# Do some checks if you want
params[:settings].each do |setting, value|
next if unallowed_setting(setting) # create unallowed_setting method if you need a filter, remove this line otherwise
model = Setting.find_or_initialize_by(name: setting)
model.value = value
model.save!
end
redirect_to :index
end
编辑
另一种可能性是保留旧代码并将 @settings 设置为 OpenStruct 实例,这样您就不必在视图中设置值,但我不能 100% 确定它会起作用:
def index
settings = {
id: nil # I think this would be needed
}
Setting.all.each do |setting|
settings[setting.name] = setting.value
end
@settings = OpenStruct.new(settings)
end
推荐阅读
- c# - 禁用自动推送远程通知ios
- asp.net - 如何在转发器中的所有单元格上放置一个复选框?
- r - 使用 R 在数据集中的多列之间重新分配字符值
- c# - c#带有基本身份验证的http post请求
- javascript - 仅在 html 打印中删除/隐藏 tfoot 最后一页
- php - 如何限制 Woocommerce 产品描述中的图像?
- python - IndexError:列表索引超出范围/无法将数字附加到数组
- python - 每次应用程序运行或日志大小达到最大值或日期更改时,如何在 python 中生成一个新的日志文件?
- php - 如何将文本转换为 utf32 编码
- angularjs - 如何仅将选定的行从handsontable导出到csv