5

忍不住尝试了重新启动的RailsForum并在这里交叉发布了这个问题。

我有以下表单对象(在 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

我可以在我的新/创建方法中使用这个表单对象

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

但是,我没有成功将它用于编辑/更新过程......

是否可以使用表单对象进行编辑/更新,如果可以,该怎么做?

4

1 回答 1

6

您必须在 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 %>
于 2015-02-22T11:07:00.150 回答