Form_for without ActiveRecord, form action is not updated

I use the API instead of the database, so I do not use ActiveRecord, but ActiveModel (basically I would like here: railscasts.com/episodes/219-active-model)

The thing is, when I try to edit an element (in my case parking), the form action is still the create action, not the update action.

so when I go / parkings / 2 / edit to edit the parking, the form remains:

<form accept-charset="UTF-8" action="/parkings" class="form-horizontal" id="new_parking" method="post"> 

when it should be more like a hidden put field and parkings / 2 as an action:

 <form accept-charset="UTF-8" action="/parkings/2" class="form-horizontal" id="edit_parking" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="_method" type="hidden" value="put" /> 

Does anyone know where the method and form_for action are set according to the route? I am trying to do as close as if I were using ActiveRecord with a database.

Here is the code:

_form.html.erb

 <%= form_for(@parking, :html => { :class => "form-horizontal" }) do |f| %> ... <% end %> 

edit.html.erb and new.html.erb, just

 <%= render 'form' %> 

controller

 class ParkingsController < ApplicationController def index @parkings = Parse.get("Parking") respond_to do |format| format.html format.json { render :json => @parking } end end def new @parking = Parking.new respond_to do |format| format.html format.json { render :json => @parking } end end def edit @parking = Parking.find(params[:id]) respond_to do |format| format.html format.json { render :json => @parking } end end def create @parking = Parking.new(params[:parking]) if (@parking.save) flash[:success] = "Parking was just added!" redirect_to :action => "new" else render :action => "new" end end def update # Testing parking = Parse.get("Parking", params[:id]) parking.delete("updatedAt") parking["name"] = params[:parking][:name] parking.save redirect_to :action => "index" end 

Model

 class Parking include ActiveModel::Validations include ActiveModel::Conversion extend ActiveModel::Naming attr_accessor :name, :address, :city, :longitude, :latitude, :contributor_name, :contributor_email validates_presence_of :name, :address, :city, :longitude, :latitude @id = nil def initialize(attributes = {}) attributes.each do |name, value| send("#{name}=", value) end end def self.find(id) @id = id raw = Parse.get("Parking", @id.to_s) parking = Parking.new parking.name = raw["name"] parking.address = raw["address"] parking.city = raw["city"] parking.longitude = raw["location"]["longitude"] parking.latitude = raw["location"]["latitude"] parking.contributor_name = raw["contributorName"] parking.contributor_email = raw["contributorEmail"] return parking end def save if (!valid?) return false else parking = Parse::Object.new("Parking") data = { :longitude => longitude.to_f, :latitude => latitude.to_f } point = Parse::GeoPoint.new(data) parking["location"] = point parking["name"] = name parking["address"] = address parking["city"] = city parking["contributorName"] = contributor_name parking["contributorEmail"] = contributor_email if (parking.save) return true end end end def persisted? false end end 

Please note that the creation works, and if I add my parking identifier in the form action = "using Web Inspector or Firebug and add: method =>" put "to my_for form, my record is updated successfully.

The real problem here is actually the form_for action and method, which does not update when I edit the parking and stay as if I were adding a new one.

I'm still learning Rails, so sorry if some information is not clear!

Thanks!

--- SOLUTION ---

was saved? should not only return false, but my model needs to define a method that returns the identifier of the object (so that they can update the action = ""), so here is my updated model:

 class Parking include ActiveModel::Validations include ActiveModel::Conversion extend ActiveModel::Naming attr_accessor :objectId, :name, :address, :city, :longitude, :latitude, :contributor_name, :contributor_email validates_presence_of :name, :address, :city, :longitude, :latitude @id = nil def initialize(attributes = {}) attributes.each do |name, value| send("#{name}=", value) end end def self.find(id) raw = Parse.get("Parking", id.to_s) parking = Parking.new parking.objectId = id parking.name = raw["name"] parking.address = raw["address"] parking.city = raw["city"] parking.longitude = raw["location"]["longitude"] parking.latitude = raw["location"]["latitude"] parking.contributor_name = raw["contributorName"] parking.contributor_email = raw["contributorEmail"] return parking end def save if (!valid?) return false else parking = Parse::Object.new("Parking") data = { :longitude => longitude.to_f, :latitude => latitude.to_f } point = Parse::GeoPoint.new(data) parking["location"] = point parking["name"] = name parking["address"] = address parking["city"] = city parking["contributorName"] = contributor_name parking["contributorEmail"] = contributor_email if (parking.save) return true end end end def update_attributes(aParking) parking = Parse.get("Parking", @id.to_s) parking.delete("updatedAt") parking["name"] = aParking["name"] parking.save return true end def destroy parking = Parse.get("Parking", @id) #parking.parse_delete end def id return self.objectId end def persisted? !(self.id.nil?) end end 
+7
source share
3 answers

I think your problem is in your persisted? model method persisted? . Since it always returns false, Rails always thinks that it is creating a form for the newly created record, so it uses POST and sends the collection URL.

This method needs some kind of logic, so existing entries return true, and new entries return false.

+6
source

Hi friend, you can tell the form developer which method to use. Try

 <%= form_for(@parking, :method => ["new", "create"].include?(action_name) ? :post : :put, :html => { :class => "form-horizontal" }) do |f| %> ... <% end %> 
+1
source

If you are not using ActiveRecord, you should use 'form_tag' instead of 'form_for'

-one
source

All Articles