(如何)我可以使用表单对象进行编辑/更新例程吗?

时间:2013-08-23 18:59:34

标签: ruby-on-rails ruby-on-rails-4 design-patterns edit

无法抗拒试用重新发布的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

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

是否可以使用表单对象进行编辑/更新,如果可以,将如何完成?

1 个答案:

答案 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 %>