I started using Ruby on Rails around four years ago, but I usually just played with trivial examples, and never really dived into it. Now that I am developing something not-so-trivial, it’s good opportunity to really understand the concept, instead of walking around it all the time.

The problem I would like to discuss in this post is form submission. Using Rails resource generator, we could get complete CRUD for a model, and it works out of the box, but it’s a black box. This time, let’s create part of it manually to gain some insight.

rails new form_submit
cd form_submit
bundle
rails g controller home edit

We wouldn’t use rails model generator, so we just create a activemodel compatible model.

module HomeHelper class UserModel include ActiveModel::Model attr_accessor :name, :age end end

In the edit action, we would instantiate an object of that model, and pass it to the view.

include HomeHelper

def edit @user = UserModel.new( name: ‘albert’, age: 30 ) end

The view contains a form, and looks like the following. The as part would show itself when we look at the submitted data.

%h1 Home#edit

= simple_form_for @user, as: :user_model, url: ‘’ do |f| = f.input :name = f.input :age, collection: 18…60

= f.submit 'Save'

Add one more method update in home controller to handle form submission, and adding the rule for that in the routing file.

def update redirect_to action: :edit #since we don’t know what to write here for now end

config/routes.rb

post ‘home/edit’, to: ‘home#update’

If we test this in the browser, and try to submit the form, we could see the submitted data in the console, something like:

Parameters: { … “user_model”=>{“name”=>“albert”, “age”=>“30”}, “commit”=>“Save”}

We could construct the model using the submitted data, and render it using the edit view. Just for fun, we would increment the age value. Since the model is not backed up by a table in database, its type is unknown; hence the string to integer conversion.

def update @user = UserModel.new(params[:user_model]) @user.age = @user.age.to_i + 1 render :edit end

The conversion is not needed if this model is an actual active model. In fact, let’s see how much needs to be changed, if we replace the model with a real active model.

rails g model User name:string age:integer rake db:migrate

Actions in the controller need to be updated to use the new model. The conversion is not needed, for its type is specified when we create the model. In addition, the key in submitted data becomes :user, which is corresponding to the model name. At last, we need to permit fields meant to be updated explicitly because of Strong Parameters

def edit @user = User.new( name: ‘albert’, age: 30 ) end

def update @user = User.new(params.require(:user).permit(:name, :age)) @user.age = @user.age + 1 render :edit end

So is the view:

= simple_form_for @user, url: ‘’ do |f| = f.input :name = f.input :age, collection: 18…60

= f.submit 'Save'

The complete code is available here