首先要做的事
用:
- 导轨4
- Oracle 增强型适配器 Rails4 分支
我在现有数据库上映射了多对多关系。我的模型看起来像这样:
class EventMap < ActiveRecord::Base
self.table_name="TAKE_PART"
self.primary_key="id"
belongs_to :event, foreign_key: "lottery_event_id"
belongs_to :entrant, foreign_key: "address_id"
end
class Event < ActiveRecord::Base
self.table_name="THE_EVENT"
self.primary_key="id"
has_many :event_maps, :foreign_key => "lottery_event_id"
has_many :entrants, :through => :event_maps
accepts_nested_attributes_for :entrants, :reject_if => :all_blank
end
class Entrant < ActiveRecord::Base
self.table_name="ADDRESSES"
self.primary_key="id"
self.set_date_columns :date_of_birth
has_many :events, :through => :event_maps
has_many :event_maps, :foreign_key => "address_id"
end
我的投票页面的静态页面控制器
...
def vote
@event=Event.find_by(id: 4227)
@entrants=@event.entrants
@entrant=@event.entrants.build
end
...
投票视图:
<%= form_for(@event) do |f| %>
<%= f.fields_for :entrant do |builder| %>
<%= render "/entrants/fields", :f => builder %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
参赛者/字段部分:
<% if @entrant.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@entrant.errors.count, "error") %> prohibited this entrant from being saved:</h2>
<ul>
<% @entrant.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :id %>
<div class="field">
<%= f.label :lastname %><br>
<%= f.text_field :lastname %>
</div>
<div class="field">
<%= f.label :firstname %><br>
<%= f.text_field :firstname %>
</div>
<div class="field">
<%= f.label :street %><br>
<%= f.text_field :street %>
</div>
<div class="field">
<%= f.label :country_id %><br>
<%= f.number_field :country_id %>
</div>
<div class="field">
<%= f.label :city %><br>
<%= f.text_field :city %>
</div>
<div class="field">
<%= f.label :telephone %><br>
<%= f.text_field :telephone %>
</div>
<div class="field">
<%= f.label :email %><br>
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :date_of_birth %><br>
<%= f.date_select :date_of_birth %>
</div>
<div class="field">
<%= f.label :lang_id %><br>
<%= f.text_field :lang_id %>
</div>
<div class="field">
<%= f.label :added %><br>
<%= f.date_select :added %>
</div>
<div class="field">
<%= f.label :salut %><br>
<%= f.text_field :salut %>
</div>
<div class="field">
<%= f.label :zip %><br>
<%= f.text_field :zip %>
</div>
<div class="field">
<%= f.label :newsletter %><br>
<%= f.check_box :newsletter %>
</div>
<div class="field">
<%= f.label :company %><br>
<%= f.text_field :company %>
</div>
表单现在提交到事件控制器PATCH
class EventsController < ApplicationController
before_action :set_event, only: [:show, :edit, :update, :destroy]
...
# PATCH/PUT /events/1
# --> HOW DO I SAVE THE SUBMITTED ENTRANT HERE??? <--
def update
respond_to do |format|
if @event.update(event_params)
format.html { redirect_to @event, notice: 'Event was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @event.errors, status: :unprocessable_entity }
end
end
end
...
private
# Use callbacks to share common setup or constraints between actions.
def set_event
@event = Event.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def event_params
params.require(:event).permit(:id, :lottery_id, :events_dates_id, :event_date, :event_location, :tickets_for_winner, :prize, :tickets_internally,
:entrants_attributes => [:id, :lastname, :firstname, :street, :country_id, :city, :telephone, :email, :date_of_birth, :lang_id, :added, :salut, :zip, :newsletter, :company])
end
end
如何向Event
注册Entrant
,仅将数据添加到中间模型EventMap
,因为Event
将始终存在?
我是否需要在我的模型中包含accepts_nested_attributes_for
才能跨表传播更改(我无法从文档中完全弄清楚这有什么作用)?我是否需要通过Entrant
表单发送其他参数来更新EventMap
?
主要目标:我想要一个参赛者可以注册现有活动的表格!
很难判断你的表格,因为我们看不到任何;)
但是您能够创建嵌套属性是对的,从嵌套属性,您需要设置accepts_nested_attributes_for :some_model, :some_other_model
如果您发现文档令人困惑,请咨询 Railscasts:http://railscasts.com/episodes/196-nested-model-form-part-1http://railscasts.com/episodes/197-nested-model-form-part-2
您需要自定义逻辑并且必须定义自定义逻辑,Rails 不会自动更新所有内容,它必须按照您的建议在更新控制器中定义。
我可能会做一些类似的事情:
def update
entrant = Entrant.find(params[:entrant_id])
event = Event.find(params[:event_id])
EventMap.create!(event: event, entrant: entrant)
#.... go on with usual stuff
# Alternatively you could use build
event_map = EventMap.new
event_map.build(event: event, entrant: entrant)
end