我在表单中有多个复选框,其中我将每个字段的结果存储在我在模型中使用attr_accessor:attribute指定的相应临时字段中。我想用逗号分隔符将这些字段的内容加入到一个字段中,并将其存储到数据库中。
我的完整表格是这样的:
<%= form_for @company do |f| %>
<% if @company.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@company.errors.count, "error") %> prohibited
this company from being saved:</h2>
<ul>
<% @company.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<p>
<%= f.label :name %><br>
<%= f.text_field :name,class:'form-control' %>
</p>
<p>
<%= f.label :grade %><br>
<%= f.select(:grade, options_for_select([['Dream', 'dream'], ['A++', 'a++'], ['A+', 'a+'],['A', 'a']])) %>
</p>
<p>
<%= f.label :beCutoff %><br>
<%= f.text_field :beCutoff,class:'form-control' %>
</p>
<%= f.label :branchesAllowed %><br>
<%= f.check_box :coe, {}, "COE", "" %><%= label_tag :COE %><br>
<%= f.check_box :ece, {}, "ECE", ""%><%= label_tag :ECE %><br>
<%= f.check_box :ice, {}, "ICE", ""%><%= label_tag :ICE %><br>
<%= f.check_box :it, {}, "IT", ""%><%= label_tag :IT %><br>
<%= f.check_box :mpae, {}, "MPAE", ""%><%= label_tag :MPAE %><br>
<%= f.check_box :bt, {}, "BT", ""%><%= label_tag :BT %><br>
<%= f.check_box :is, {}, "IS", ""%><%= label_tag :IS %><br>
<%= f.check_box :sp, {}, "SP", ""%><%= label_tag :SP %><br>
<%= f.check_box :pc, {}, "PC", ""%><%= label_tag :PC %><br>
<p>
<%= f.label :backsAllowed %><br>
<%= f.text_field :backsAllowed,class:'form-control' %>
</p>
<p>
<%= f.label :details %><br>
<%= f.text_field :details,class:'form-control' %>
</p>
<p>
<%= f.label :package %><br>
<%= f.text_field :package,class:'form-control' %>
</p>
<p>
<%= f.label :xiiCutoff %><br>
<%= f.text_field :xiiCutoff,class:'form-control' %>
</p>
<p>
<%= f.label :xCutoff %><br>
<%= f.text_field :xCutoff,class:'form-control' %>
</p>
<%= f.label :deadline %><br>
<div class='input-group date' id='datetimepicker1'>
<%= f.text_field :deadline ,class:'form-control',:readonly=>true%>
<span class="input-group-addon" ><span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker1').datetimepicker({format: 'YYYY-MM-DD HH:mm:ss '});
});
</script>
</div>
<p>
<%= f.submit %>
</p>
<% end %>
我在模型中指定字段:coe,:ece,:ice等作为attr_accessor:
class Company < ActiveRecord::Base
attr_accessor :coe,:ece,:ice,:it,:mpae,:bt,:is,:pc,:sp
validate :deadline_on_or_before_now
def deadline_on_or_before_now
errors.add(:deadline, "can't be in the past") if
!deadline.blank? and deadline < (Time.zone.now+19800).to_datetime
end
validates :name, presence: true,
length: { minimum: 2 };
validates :grade,:beCutoff,:details,:package, presence: true;
validates_inclusion_of :beCutoff,:xiiCutoff,:xCutoff, :in=> 0..100,:message=>"Out of Range";
end
我的控制器看起来像这样:
class CompaniesController < ApplicationController
def new
@company = Company.new
end
def edit
@company = Company.find(params[:id])
end
def update
@company = Company.find(params[:id])
if @company.update(company_params)
redirect_to @company
else
render 'edit'
end
end
def create
@company = Company.new(company_params)
if @company.save
redirect_to @company
else
render 'new'
end
end
def index
@companies = Company.all
end
def destroy
@company = Company.find(params[:id])
@company.destroy
redirect_to companies_path
end
def show
@company = Company.find(params[:id])
end
private
def company_params
params.require(:company).permit(:name, :beCutoff,:grade,:xiiCutoff,:xCutoff,:backsAllowed,:details,:package,:deadline,:branchesAllowed,:coe,:ece,:ice,:it,:mpae,:bt,:is,:sp,:pc) if params[:company]
end
end
我想加入:coe,:ece,:ice等等字段并将其存储到:branchesAllowed(字符串字段)字段,带有一个commma分隔符,并且只要我需要单独使用它们就能分割这个字段。 我正在使用带有rails 4.1的postgresql。
答案 0 :(得分:1)
如果我想这样做,我会去存储在字符串字段中的哈希。
before_save :create_string
def create_string
fields = {}
fields[:coe]=coe
fields[:ece]=ece
# etcetera
branchesAllowed = fields.to_s # hash to string and then store the string
end
然后,检索值(比如在控制器或视图中):
values = eval(@company.branchesAllowed) # reversely, evaluate string to hash
@coe = values[:coe]
@ece = values[:ece]
# etcetera
答案 1 :(得分:0)
我会稍微改变一下。假设这些是您希望能够设置的Company
的所有属性,您可以使用单个整数字段来存储此数据,方法是创建属性类型的数组并使用该数组中每个属性的索引作为二进制值,您可以使用它来标识是否设置了属性。
观看此Railscast以获得完整的解释,因为Ryan比我做得更好:http://railscasts.com/episodes/189-embedded-association
答案 2 :(得分:0)
最快最脏的方式是简单地连接模型中方法中的字段,并在before_save
回调中调用该方法:
class Company < ActiveRecord::Base
# . . .
before_save :combine_branches # or choose other callback type respectively
def combine_branches
self.branchesAllowed = ""
self.branchesAllowed += "COE" if coe
self.branchesAllowed += "ECE" if eve
self.branchesAllowed += "ICE" if ice
# … and so on …
end
end
现在,当您在控制器中调用save
或update
时,回调会在写入数据库之前触发并设置branchesAllowed
字段。
干(呃)解决方案可能如下所示:
class Company < ActiveRecord::Base
# keep a constant of possible branches tied to the model
POSSIBLE_BRANCHES = [:coe, :ece, :ice, :it, :mpae, :bt, :is, :pc, :sp]
# add the branches as virtual attributes (only assign methods)
attr_writer *POSSIBLE_BRANCHES
# add virtual attributes reader methods
# --> define every branch as method, that looks if the value is currenly
# stored in the branchesAllowed string and return true or false
POSSIBLE_BRANCHES.each do |pb|
define_method(pb) do
self.banchesAllowed.split(',').include?(pb.to_s.upcase)
end
end
# add the callback to combine the branches
before_save :combine_branches
def combine_branches
self.banchesAllowed = POSSIBLE_BRANCHES.select { |pb| !!self.send(pb) }.map(&:upcase).join(',')
end
end
然后您也可以在视图中使用它们:
<%= f.label :branchesAllowed %><br>
<% Company::POSSIBLE_BRANCHES.each do |pb| %>
<%= f.check_box pb, {}, pb.to_s.upcase, "" %><%= label_tag pb.to_s.upcase %><br>
<% end %>
因此,如果您想稍后添加另一个分支,只需在数组常量中添加另一个符号即可完成。希望有所帮助。
<强>更新强>
由于复选框中的boolean
值默认使用'1'
和'0'
(作为字符串),因此我不完全确定虚拟属性读取器方法是否应该返回而不是布尔值。