我有一个很多领域的模型,其中许多领域密切相关。
说我有模特:Fruit
有attrs:fruit_type: ['apple', 'banana']
,fruit_color: ['red', 'green', 'yellow']
,is_rotten: ['true', 'false']
。
现在我想为这些模型创建一些超级用户友好的创建/编辑表单,用户可以在其中编辑属性。 Rails非常适合:
创建一个类似的表单:
= form_for @fruit do |f|
= f.select :fruit_type, options_for_select(['apple', 'banana'])
= f.select :fruit_color, options_for_select(['red', 'green', 'yellow'])
= f.check_box :is_rotten
= f.submit "save!"
将为您提供rails的所有巨大优势,使用非常有限的代码量自动呈现该属性当前正在使用的值等。
现在。实际上,如果这将是超级用户友好和快速使用,组合其中一些字段将更有意义,因此用户只需从组合列表中选择一个项目,然后生成关于模型的正确数据:
= form_for @fruit do |f|
= f.select :fruit_color_and_fruit_type, options_for_select(['Yellow apple', 'Red apple', 'Green apple', 'Yellow banana'])
= f.check_box :is_rotten
= f.submit "save!"
然而,这不是直接从轨道支持的原因。那么,我可以使用什么模式来使这个游戏很好用rails'做事的标准方式(强大的参数,预先设定表格中的价值,属性质量分配等),所以我不必在任何地方进行黑客攻击和硬编码?
答案 0 :(得分:0)
您可以提交组合值,然后使用控制器中的逻辑将它们拆分为正确的属性。我认为这种方式更清洁,更可靠。
应用/模型/ fruit.rb 强>
class Fruit < ActiveRecord::Base
attr_accessor :fruit_color_and_fruit_type
...
end
应用/控制器/ fruit_controller.rb 强>
class FruitController < ApplicationController
...
def create
attrs = fruit_params
attrs[ :fruit_color ] = attrs[ :fruit_color_and_fruit_type ].split( ' ' )[ 0 ].downcase( )
attrs[ :fruit_type ] = attrs[ :fruit_color_and_fruit_type ].split( ' ' )[ 1 ].downcase( )
@fruit = Fruit.new( attrs )
if @fruit.save
flash[ :success ] = 'New fruit created.'
redirect_to users_path
else
render :new
end
end
...
private
def fruit_params
params.require( :fruit ).permit(
:fruit_color_and_fruit_type,
:is_rotten
)
end
end
也可以提交预先格式化的信息,这样您就不必在控制器中弄乱它。只需使用隐藏的输入和一点JavaScript。
应用/模型/ fruit.rb 强>
class Fruit < ActiveRecord::Base
attr_accessor :fruit_color_and_fruit_type
...
end
应用/控制器/ fruit_controller.rb 强>
class FruitController < ApplicationController
...
private
def fruit_params
params.require( :fruit ).permit(
:fruit_color,
:fruit_color_and_fruit_type,
:fruit_type,
:is_rotten
)
end
end
应用/视图/果/ new.html.haml 强>
%script
:plain
$( document ).ready( function ( ) {
// the ids used here are the ones automatically assigned by form_for.
$( document ).on( 'change', '#fruit_fruit_color_and_fruit_type', function ( ) {
var value = $( this ).val( );
$( '#fruit_fruit_color' ).val( value.split( ' ' )[ 0 ].toLowerCase( ) );
$( '#fruit_fruit_type' ).val( value.split( ' ' )[ 1 ].toLowerCase( ) );
} );
} );
= form_for @fruit do | f |
= f.hidden_field :fruit_color
= f.hidden_field :fruit_type
= f.select :fruit_color_and_fruit_type, options_for_select(['Yellow apple', 'Red apple', 'Green apple', 'Yellow banana'])
= f.check_box :is_rotten
= f.submit 'Save!'