无法抗拒试用重新发布的RailsForum并转发此问题here。
我有以下表单对象(在Rails 4中)
class StationForm
include Virtus
include ActiveModel::Model
# I think this is unnecessary
# extend ActiveModel::Naming
# include ActiveModel::Conversion
# include ActiveModel::Validations
# Station
attr_reader :station
attribute :station_name, String
attribute :station_description, String
# Address
attr_reader :address
attribute :address_url, String
attribute :address_priority, Integer
attribute :address_is_active, Boolean
def persisted?
false
end
def save
if valid?
persist
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
end
我可以在new / create方法中使用这个表单对象
class StationsController < ApplicationController
def new
@station_form = StationForm.new
end
def create
@station_form = StationForm.new(station_form_params)
@station_form.save
redirect_to station_path(@station)
end
private
def station_form_params
params.require(:station_form).permit(:station_name, :station_description, :address_url, :address_priority, :address_is_active)
end
end
但是,我没有成功将它用于编辑/更新程序......
是否可以使用表单对象进行编辑/更新,如果可以,将如何完成?
答案 0 :(得分:1)
你必须使用&#34;初始化&#34; StationForm对象中的方法用于编辑。如果你传递一个id,它将假设该对象已经存在,并从那里我们可以将它视为一个持久化对象。 另外添加&#34;更新&#34;更新对象属性的方法。
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
使用&#34;坚持&#34;和&#34; id&#34;来自_form.html.erb
中的StationForm的方法 <%= 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 %>