我有3个型号,
这些模型之间的关系是多对多关系。
单位模型
has_many :unitrentperiods, inverse_of: :unit
has_many :rentperiods, :through => :unitrentperiods
accepts_nested_attributes_for :unitrentperiods
unitrentperiod模型
belongs_to :unit
belongs_to :rentperiod
租期模型
has_many :unitrentperiods, inverse_of: :rentperiod
has_many :units, :through => :unitrentperiods
我有一个单位表格,我可以在这里创建一个新单位或编辑单位。 我想让我的单位形式不仅能够管理我的单位,而且能够管理我的" unitrentperiod"同样,假设我有2个租期,如
"6 months"
"12 months"
我希望我的单位表格能够显示那些租金期间还有价格输入,所以当我保存单位表格时,我还会根据数据库中的租期来保存2个单位期限,我在我的观点中这样做了:
<style>
.divCB {
margin-right: 10px
}
</style>
<%= form_for(@unit) do |f| %>
<% if @unit.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@unit.errors.count, "error") %> prohibited this unit from being saved:</h2>
<ul>
<% @unit.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<% end %>
<div class="page-header">
<div class="row">
<div class="col-md-7">
<h1 class="h2 page-title">Manage Unit</h1>
<div class="text-muted page-desc"></div>
</div>
<div class="col-md-5 charts">
<div class="row">
</div>
</div>
</div>
</div>
<!-- Breadcrumb -->
<ol class="breadcrumb">
<li class="active">Manage Unit</li>
<!-- Breadcrumb Menu-->
</ol>
<div class="container-fluid">
<div class="animated fadeIn">
<!--/.row-->
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<strong>Unit Form</strong>
</div>
<%= form_for @unit, html: {class: "form-horizontal"} do |f| %>
<div class="card-block">
<div class="form-group row">
<%= f.label 'Apartement', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= collection_select(:unit, :apt_id, @apts, :id, :apt_name, {:prompt => "Please select an Apartement"}, {:id => 'apartements_select', :class => "select", :style => "width:240px"}) %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Tower', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= collection_select(:unit, :tower_id, @towers, :id, :tower_name, {:prompt => "Select a Tower"}, {:id => 'towers_select', :class => "select", :style => "width:240px"}) %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Unit number', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :unitno, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Unit size', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :unitsize, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Unit view', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.select :unitview, options_for_select(@unit_views.collect { |s| [s[0].humanize, s[0]] }, selected: @unit.unitview), {} , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Room Type', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= collection_select(:unit, :room_type_id, @roomtypes, :id, :room_type_desc, {:prompt => false}, class: "form-control") %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Unit floor', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :unitfloor, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Unit description', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :unitdesc, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Total bed', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :totalbedroom, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Furnish', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.select :furnish, options_for_select(@furnish_types.collect { |s| [s[0].humanize, s[0]] }, selected: @unit.furnish), {} , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'For sell', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.select :isforsell, options_for_select( [ ['No', 0], ['Yes', 1] ], selected: @unit.isforsell), {} , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Sell price', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.text_field :sellprice, class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'For rent', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.select :isforrent, options_for_select( [ ['No', 0], ['Yes', 1] ], selected: @unit.isforrent), {} , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Rent price', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<table>
<% @rentperiods.each do |rentperiod| -%>
<tr>
<td><%= rentperiod.rentmonth %> Month</td>
<td>
<%= fields_for(@unitrentperiods) do |elem| %>
<%= elem.text_field :rentprice, class: 'col-md-4 form-control' %> IDR
<%= elem.hidden_field :rentperiod_id, :value => rentperiod.id %>
<% end %>
</td>
</tr>
<% end -%>
</table>
</div>
</div>
<div class="form-group row">
<%= f.label 'Unit status', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.select :unitstatus, options_for_select(@unit_statuses.collect { |s| [s[0].humanize, s[0]] }, selected: @unit.unitstatus), {} , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Photo Template', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<%= f.select :template_id, options_for_select(@templates.collect { |s| [s[:type], s[:id]] }, selected: @unit.template_id), {} , class: "form-control" %>
</div>
</div>
<div class="form-group row">
<%= f.label 'Floor plan', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<div id="divFloorplan">
</div>
</div>
</div>
<div class="form-group row">
<%= f.label 'Unit plan', class: 'col-md-4 form-control-label' %>
<div class="col-md-8">
<div id="divUnitplan">
</div>
</div>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-sm btn-primary"><i class="fa fa-dot-circle-o"></i> Submit</button>
</div>
<% end %>
</div>
</div>
<!--/col-->
</div>
<!--/.row-->
</div>
</div>
<script>
$(document).ready(function()
{
$('.select').select2();
$('#apartements_select').change(function() {
$.ajax({
url: "/units/gettowers",
data: {
apt_id : $('#apartements_select').val()
},
dataType: "script"
});
$.ajax({
url: "/units/getfloorplans",
data: {
apt_id : $('#apartements_select').val()
},
dataType: "script"
});
$.ajax({
url: "/units/getunitplans",
data: {
apt_id : $('#apartements_select').val()
},
dataType: "script"
});
});
});
</script>
控制器
class UnitsController < ApplicationController
before_action :set_unit, only: [:show, :edit, :update, :destroy]
# GET /units
# GET /units.json
def index
@units = Unit.paginate(page: params[:page])
end
# GET /units/1
# GET /units/1.json
def show
end
def gettowers
# updates towers based on apartement selection
tower = Tower.where(:apt_id => params[:apt_id])
# map to name and id for use in our options_for_select
@towers = tower.map{|a| [a.tower_name, a.id]}.insert(0, "Select a Tower")
end
def getfloorplans
floorplans = Floorplan.where(:apt_id => params[:apt_id]).select("id, floorplanphoto")
@imgs = floorplans
end
def getunitplans
unitplans = Unitplan.where(:apt_id => params[:apt_id]).select("id, unitplanphoto")
@imgs = unitplans
end
def preparedata
#master tables
@apts = Apt.all
@towers = Tower.all
@roomtypes = RoomType.all
@rentperiods = Rentperiod.all
array = []
Template.all.each do |t|
hash = { :type => t.room_type.room_type_desc, :id => t.id }
array.push(hash)
end
@templates = array
#enum from model
@unit_views = Unit.unitviews
@furnish_types = Unit.furnishes
@unit_statuses = Unit.unitstatuses
end
# GET /units/new
def new
@unit = Unit.new
@unitrentperiods = @unit.unitrentperiods.build
preparedata
# @rentperiods.each do |r|
# @unit.unitrentperiods.build
# end
end
# GET /units/1/edit
def edit
#@unitrentperiods = @unit.unitrentperiods
@unitrentperiods = @unit.unitrentperiods.build
preparedata
end
# POST /units
# POST /units.json
def create
@unit = Unit.new(unit_params)
respond_to do |format|
if @unit.save
format.html { redirect_to @unit, notice: 'Unit was successfully created.' }
format.json { render :show, status: :created, location: @unit }
else
format.html { render :new }
format.json { render json: @unit.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /units/1
# PATCH/PUT /units/1.json
def update
respond_to do |format|
if @unit.update(unit_params)
format.html { redirect_to @unit, notice: 'Unit was successfully updated.' }
format.json { render :show, status: :ok, location: @unit }
else
format.html { render :edit }
format.json { render json: @unit.errors, status: :unprocessable_entity }
end
end
end
# DELETE /units/1
# DELETE /units/1.json
def destroy
@unit.destroy
respond_to do |format|
format.html { redirect_to units_url, notice: 'Unit was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_unit
@unit = Unit.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def unit_params
params.require(:unit).permit(:apt_id, :tower_id, :unitno, :unitsize, :unitview,
:room_type_id, :unitfloor,
:unitdesc, :isforsell, :sellprice, :isforrent, :furnish, :totalbedroom,
:unitstatus, :template_id, :floorplan_id, :unitplan_id,
unitrentperiods_attributes: [:rentprice, :rentperiod_id])
end
end
不知怎的,它不起作用。我错过了什么?需要一些指导才能使它发挥作用。
答案 0 :(得分:0)
At first you don't accept nested attributes, add
accept_nested_attributes_for :unitrentperiods
right below has_many :unitrentperiods
Also, you might need to configure strong parameters to allow that nested attributes parameter (or attr_accessible
if you are on Rails 3).
Gotcha here: you have to allow unitrentperiods_attributes
, not just unitrentperiods
.