Couldn't resist to try out the relaunched RailsForum and crossposted this question here.
I have the following form object (in 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
I can use this form object in my new/create methods
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
However, I don't succeed to use it for the edit/update procedures...
Is it possible to use the form object for edit/update and if yes, how would this be done?
You will have to use "initialize" method in StationForm object to use it for editing. if you pass an id, it will assume, that the object already exist and from there we can treat it as an persisted object. Also Add "update" method to update attributes of object.
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
And Controller will be like
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
use the "persisted" and "id" method from StationForm in the _form.html.erb
<%= 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 %>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With