您必须在 StationForm 对象中使用“初始化”方法才能使用它进行编辑。如果您传递一个 id,它将假定该对象已经存在,并且我们可以从那里将其视为持久对象。还添加“更新”方法来更新对象的属性。
class StationForm
include Virtus.model
include ActiveModel::Model
# I think this is unnecessary
# extend ActiveModel::Naming
# include ActiveModel::Conversion
# include ActiveModel::Validations
attr_reader :station
attribute :station_name, String
attribute :station_description, String
attr_reader :address
attribute :address_url, String
attribute :address_priority, Integer
attribute :address_is_active, Boolean
def initialize(attr = {})
if !attr["id"].nil?
@station = Station.find(attr["id"])
@address = @station.addresses.first
self[:station_name] = attr[:station_name].nil? ? @station.name : attr[:station_name]
self[:station_description] = attr[:station_description].nil? ? @station.description : attr[:station_description]
self[:address_url] = attr[:address_url].nil? ? @address.url : attr[:address_url]
self[:address_priority] = attr[:address_priority].nil? ? @address.priority : attr[:address_priority]
self[:address_is_active] = attr[:address_is_active].nil? ? @address.is_active : attr[:address_is_active]
else
super(attr)
end
end
def persisted?
@station.nil? ? false : @station.persisted?
end
def id
@station.nil? ? nil : @station.id
end
def save
if valid?
persist
true
else
false
end
end
def update
if valid?
update_form
true
else
false
end
end
private
def persist
@station = Station.create(name: station_name, description: station_description)
@address = @station.addresses.create(url: address_url, priority: address_priority, is_active: address_is_active)
end
def update_form
@station.update_attributes(
:name => self[:station_name],
:description => self[:station_description]
)
@address.update_attributes(
:url => self[:address_url],
:priority => self[:address_priority],
:is_active=> self[:address_is_active]
)
end
end
控制器会像
def new
@station = StationForm.new
end
def edit
@station = StationForm.new("id" => params[:id])
end
def create
@station = StationForm.new(station_params)
respond_to do |format|
if @station.save
format.html { redirect_to stations_path, notice: 'Station was successfully created.' }
format.json { render :show, status: :created, location: @station }
else
format.html { render :new }
format.json { render json: @station.errors, status: :unprocessable_entity }
end
end
end
def update
@station = StationForm.new(station_params.merge("id" => params[:id]))
respond_to do |format|
if @station.update
format.html { redirect_to stations_path, notice: 'Station was successfully updated.' }
format.json { render :show, status: :ok, location: @station }
else
format.html { render :edit }
format.json { render json: @station.errors, status: :unprocessable_entity }
end
end
end
在 _form.html.erb 中使用 StationForm 中的“持久”和“id”方法
<%= form_for(@station,
:url => @station.persisted? ? station_path(@station.id) : stations_path,
:method => @station.persisted? ? "put": "post") do |f| %>
<% if @station.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@station.errors.count, "error") %> prohibited this station from being saved:</h2>
<ul>
<% @station.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :station_name %><br>
<%= f.text_field :station_name %>
</div>
<div class="field">
<%= f.label :station_description %><br>
<%= f.text_field :station_description %>
</div>
<div class="field">
<%= f.label :address_url%><br>
<%= f.text_field :address_url %>
</div>
<div class="field">
<%= f.label :address_priority%><br>
<%= f.text_field :address_priority%>
</div>
<div class="field">
<%= f.label :address_is_active %><br>
<%= f.text_field :address_is_active %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>