Skip to main content
April 1, 2026Noble Desktop Publishing Team/13 min read

Forms in Rails: Processing & Editing Form Data

Master Rails Form Processing and Data Management

Core Rails Form Concepts

Strong Parameters

Security feature that requires whitelisting form parameters to prevent unauthorized data injection and protect against malicious attacks.

DRY Principle

Don't Repeat Yourself methodology using partials and private methods to eliminate code duplication and improve maintainability.

RESTful Actions

Standard CRUD operations including create, edit, and update methods that follow Rails conventions for data processing.

Topics Covered in This Ruby on Rails Tutorial:

Making the Form Work: Defining a Create Method, Making an Edit Form, Optional Bonus: DRYing up the Code Even More

Exercise Preview

preview rails forms processing

Exercise Overview

In the previous exercise we created a form, but it remains functionally incomplete—it cannot submit data yet. A critical component in the controller must be ready to receive the form data, process it systematically, and create a new movie object based on that information. In Rails' RESTful routing architecture, this essential method is called Create.

This exercise builds directly on form fundamentals by implementing the server-side logic that transforms user input into persistent database records. You'll learn how Rails handles form submissions through strong parameters—a security feature that has become standard practice in modern Rails applications since version 4.0.

  1. If you completed the previous exercises, you can skip the following sidebar. We strongly recommend finishing the previous exercises before starting this one, as each builds essential knowledge for professional Rails development. If you haven't finished them, follow the setup instructions below.

    Form Processing Workflow

    1

    Create Method

    Define controller method to receive and process form data with strong parameters validation

    2

    Edit Form

    Build edit functionality with pre-populated fields and update method for existing records

    3

    DRY Implementation

    Refactor code using partials and private methods to eliminate redundancy and improve maintainability

If You Did Not Do the Previous Exercises (3A–4A)

  1. Close any files you may have open.
  2. Open the Finder and navigate to Class Files > yourname-Rails Class
  3. Open Terminal.
  4. Type cd and a single space (do NOT press Return yet).
  5. Drag the yourname-Rails Class folder from the Finder to the Terminal window and press ENTER.
  6. Run rm -rf flix to delete your copy of the Flix site.
  7. Run Git clone https://bitbucket.org/Noble Desktop/flix.Git to copy the Flix Git repository.
  8. Type cd flix to enter the new directory.
  9. Type Git checkout 4A to bring the site up to the end of the previous exercise.
  10. Run bundle to install any necessary gems.
  11. Run yarn install—check-files to install JavaScript dependencies.
Prerequisites Required

This exercise builds on previous work. If you haven't completed exercises 3A-4A, follow the Git checkout process to get the required starting files before proceeding.

Getting Started

Before diving into form processing logic, let's ensure your development environment is properly configured and running smoothly.

  1. Open the Finder and navigate to Class Files > yourname-Rails Class

  2. Open Terminal.

  3. Type cd and a single space (do NOT press Return yet).

  4. Drag the flix folder from the Finder to the Terminal window.

  5. Make sure you're in Terminal and hit Return to change into the new folder.

  6. Type the following to launch the server:

    rails server
  7. Open a browser and navigate to localhost:3000 to verify everything is running correctly. You should see the Flix website loading without errors.

  8. We recommend opening the entire flix folder in your code editor if it supports project-wide file management (like Sublime Text, VS Code, or RubyMine).

Environment Setup

0/3

Making the Form Work: Defining a Create Method

Now we'll implement the server-side logic that processes form submissions. The create method represents the cornerstone of Rails' CRUD operations, transforming user input into database records while maintaining security through parameter filtering.

  1. In your code editor open flix > app > controllers > movies_controller.rb

  2. Create a new method right before the final end in the document as follows:

    def create
    
       end
    end

    Inside this create method we will receive and process what are called the parameters from the form submission. Rails receives and processes form data in a hash called params. An essential security feature in Rails called strong parameters requires us to explicitly whitelist the parameters we expect to receive through each form. This feature serves as a critical safeguard against mass assignment vulnerabilities and parameter injection attacks that could allow malicious users to modify data inappropriately.

    The practical implementation of this security measure means controllers must declare which parameters they will accept using a method called params.permit followed by an explicit list of expected parameters. This approach has been standard practice since Rails 4.0 and remains a fundamental security principle in modern Rails applications.

  3. Add the following bold code:

    def create
       movie_params = params.require(:movie).permit()
    end
  4. Complete the list of expected parameters by adding the following bold code (on a single line):

    movie_params = params.require(:movie).permit(:title, :description, :has_subtitles, :placement, :mpaa_rating, :release_date, :ticket_price, :runtime, :poster_image)

    Take a moment to carefully verify your work. While this parameter listing is admittedly tedious to type, it provides essential security protection that has prevented countless security breaches in production Rails applications. This explicit parameter definition ensures that only the data you expect can be processed by your application.

  5. After the parameters line (some code omitted to save space), add the following bold code to create the new movie object:

    def create
       movie_params = params.require(:movie).permit(…)
       @movie = Movie.new(movie_params)
    end

    The elegance of Rails' Active Record pattern shines through here. To create a new movie object from form data, we simply set the instance variable @movie equal to Movie.new and pass the movie_params object directly into the constructor. Rails automatically maps the parameter names to the corresponding model attributes, eliminating the need for manual field-by-field assignment.

  6. If we stopped at this point, a new movie would be created in memory but only temporarily—we need to persist this information to the database! Add the following bold code to the create method:

    @movie = Movie.new(movie_params)
       if @movie.save
          redirect_to @movie
       else
          render action: 'new'
       end
    end

    Professional web applications must provide clear feedback about the success or failure of user actions. This if/else conditional implements a standard Rails pattern: if the movie saves successfully to the database, redirect the user to view their newly created movie; if validation fails or another error occurs, render the form again with the data they've already entered, allowing them to correct any issues without losing their work.

  7. Save the file.

  8. Open flix > app > views > layouts > application.html.erb

  9. Around line 52 notice this piece of code:

    <% if flash[:alert] %>
       <div id="flash" class="alert"><%= flash[:alert] %></div>
    <% elsif flash[:notice] %>
       <div id="flash" class="notice"><%= flash[:notice] %></div>
    <% end %>

    We've implemented this flash message system in advance to streamline your development process. Through carefully crafted CSS classes, notice messages display with a professional green background to indicate success, while alert messages appear with a red background to signal errors or warnings. This visual feedback system is essential for creating intuitive user experiences.

  10. Now we need to configure Rails to display a success message in this notice area. Switch back to movies_controller.rb

  11. Add the following bold code:

    if @movie.save
       redirect_to @movie, notice: 'Movie was created successfully.'
    else
  12. Save the file.

  13. Switch to the browser and navigate to localhost:3000/movies/new

  14. Let's test our form with actual movie data! We've prepared a text file with complete movie information to save you time on data entry. Switch to the Finder.

  15. Navigate into Class Files > yourname-Rails Class > flix snippets and double–click on gone_with_the_windows.txt to open it (it will likely open in TextEdit).

  16. Arrange your windows so gone_with_the_windows.txt and the browser window are visible side-by-side for efficient data entry.

  17. Copy and paste all of the information from gone_with_the_windows.txt into the corresponding form fields. For the dropdown fields, set the Placement to In Theaters, MPAA Rating to PG, and Release Date to any future date as specified in the text file.

  18. When complete, click Create Movie.

    You should be redirected to localhost:3000/movies/4 where you can view the new movie page for Gone With the Windows along with a professional green success banner confirming the successful creation of your new movie record.

Rails receives and processes form permissions in a hash called params. Strong parameters requires us to white-list those parameters we expect to receive through each form.
Essential security concept in Rails form processing

Movie Form Parameters

Text Fields
4
Selection Fields
2
Date/Number Fields
3

Making an Edit Form

Forms that only create new records represent just half of a complete CRUD interface. Professional applications require robust editing capabilities. Let's imagine the PR Department has identified errors in our Text M for Murder movie: the rating should be R instead of PG, and the description incorrectly refers to an ex-golfer rather than an ex-tennis star.

Rather than starting from scratch, we'll leverage our existing form infrastructure as a foundation for building edit functionality—a practical approach that demonstrates Rails' commitment to code reusability.

  1. Switch to movies_controller.rb in your code editor.

  2. Add the following edit method directly above the final end of the document, around line 36:

    def edit
          @movie = Movie.find(params[:id])
       end
    end
  3. Save the file.

  4. Open flix > app > views > movies > new.html.erb in your code editor.

  5. Choose File > Save As.

  6. Name the file edit.html.erb and ensure it's saved in: flix > app > views > movies (it should default to this location, but always verify the file path).

  7. Find the header on the first line of the document:

    <h1>Add Movie</h1>
  8. Edit the line to read:

    <h1>Edit Movie</h1>

    Following Rails conventions, we'll need a corresponding update method to process the edited form data. Just as the create method processes data from the new page, the update method handles data from the edit page, completing the CRUD cycle.

  9. Save the file.

  10. Switch to movies_controller.rb

  11. Around line 40 add the following bold code:

    def update
    
       end
    end
  12. Copy the contents of the edit method above and paste the code in the update method as shown below:

    def update
       @movie = Movie.find(params[:id])
    end
  13. Find the following piece of code from earlier in the file (around line 27):

    movie_params = params.require(:movie).permit(:title, :description, :has_subtitles, :placement, :mpaa_rating, :release_date, :ticket_price, :runtime, :poster_image)

  14. Copy this parameter definition code.

  15. Paste the code inside the update method:

    def update
       @movie = Movie.find(params[:id])
       movie_params = params.require(:movie).permit(…)
    end
  16. Add the following bold code to complete the update method:

    @movie = Movie.find(params[:id])
       movie_params = params.require(:movie).permit(…)
       if @movie.update(movie_params)
          redirect_to @movie, notice: 'Movie was successfully updated.'
       else
          render action: 'edit'
       end
    end
  17. Save the file.

  18. In a browser navigate to localhost:3000/movies/1/edit

  19. The edit form should be displaying properly with all existing data pre-populated! In the Description text area, change ex-golfer to ex-tennis star.

  20. Change the MPAA Rating to R. (You may notice that the dropdown menu appears empty instead of showing the current rating—we'll address this interface issue momentarily.)

  21. Click Update Movie.

    You should be redirected to localhost:3000/movies/1 with a professional green success banner displaying: Movie was successfully updated.

    The efficiency of this implementation showcases Rails' intelligent form helpers. By copying and adapting the existing form with minimal modifications to the heading, and leveraging the @movie instance variable, Rails automatically pre-populated all form fields with the existing movie's information—no additional configuration required.

Create vs Edit Methods

FeatureCreateEdit
Data SourceNew form inputExisting database record
Instance VariableMovie.new(params)Movie.find(params[:id])
Success Actionredirect_to @movieredirect_to @movie
Failure Actionrender 'new'render 'edit'
Recommended: Both methods follow similar patterns but handle data sources differently

DRYing up the Code with Partials

While our rapid development approach achieved functional results, the current implementation violates a fundamental principle of professional software development. We now have identical form code duplicated across two separate files—the new and edit views. As we add new fields to the movie form (and we'll be implementing several enhancements!), we'll face the maintenance nightmare of updating both forms identically, creating opportunities for bugs and inconsistencies.

A cornerstone principle in Rails development is DRY (Don't Repeat Yourself). Code duplication—like our current approach with two identical forms—creates significant maintenance challenges, introduces bugs, and violates professional development standards. Fortunately, Rails provides sophisticated tools to maintain DRY code, and we'll implement one of the most powerful: partials.

A partial functions as a reusable sub-view that can be rendered from within other views. Unlike standard views, partials aren't typically called directly by controllers—they're designed for inclusion and reuse. You can instantly identify partial files by their naming convention: they always begin with an underscore, like _partial_name.html.erb.

  1. Switch to edit.html.erb in your code editor.

  2. Perform a File > Save As.

  3. Save the new file as _form.html.erb (the underscore prefix is crucial—it designates this as a partial!) and verify it's saved in flix > app > views > movies (this should be the default location).

  4. Delete the heading on the first line. (This heading needs to be context-specific, changing based on whether you're editing an existing movie or creating a new one.)

  5. Save the file.

  6. Re-open edit.html.erb (located in flix > app > views > movies).

  7. Delete everything except the first line (the heading).

  8. Add the following bold code:

    <h1>Edit Movie</h1>
    <%= render 'form' %>
  9. Save the file.

  10. Open new.html.erb (located in flix > app > views > movies).

  11. Delete everything except the first line (the heading).

  12. Add the following bold code:

    <h1>Add Movie</h1>
    <%= render 'form' %>
  13. Save the file.

  14. Both view files now reference the same form partial, implementing true code reuse instead of duplication. Test this implementation by navigating to localhost:3000/movies/new in your browser—the form for creating movies should function identically to before, despite now being rendered as a partial.

  15. Navigate to localhost:3000/movies/4/edit/ and verify that the edit form displays correctly as well. Our code now adheres to DRY principles while maintaining full functionality. However, if you examine the MPAA Rating field on the edit page, you'll notice it appears blank—it's not displaying the existing rating for this movie because we haven't configured the options_for_select helper to remember selected values. Let's resolve this user interface issue.

  16. Switch to _form.html.erb in your code editor.

  17. Locate the following line of code, around line 24:

    <% mpaa_ratings = options_for_select ["G", "PG", "R", "NR"] %>
  18. Add the following bold code—pay careful attention to the comma placement!

    <% mpaa_ratings = options_for_select ["G", "PG", "R", "NR"], selected: @movie.mpaa_rating %>
  19. Save the file.

  20. Return to your browser, reload localhost:3000/movies/4/edit and confirm that the MPAA Rating field now correctly displays the existing rating!

  21. In Terminal, press CTRL–C to gracefully shut down the development server.

Partial File Naming

Partials always start with an underscore (_form.html.erb) but are rendered without it using render 'form'. This convention helps identify reusable view components.

Benefits of Using Partials

Pros
Eliminates duplicate form code between new and edit views
Single location for form updates reduces maintenance overhead
Follows Rails DRY principle for better code organization
Automatic field population works with both create and edit actions
Cons
Requires additional file management with underscore naming
May need specific helper configurations for complex fields
Initial setup takes more time than simple copy-paste approach

Optional Bonus: DRYing up the Code Even More

Professional Rails developers recognize that DRY principles extend beyond views into controller logic. Our current controller contains several instances of code repetition that, while functional, don't meet enterprise-level standards for maintainability and organization.

  1. Switch to movies_controller.rb in your code editor.

  2. Directly before the final end at the bottom, add the following bold private method:

    end
    
       private
          def movie_params
       end
    end

    Private methods can only be invoked from within the controller itself, never from external sources or routes. The methods we're implementing here serve as non-action helper methods. Rails best practices dictate that non-action methods should be private, creating a clear architectural distinction between methods accessible via routing and internal helper methods that support controller functionality.

  3. Navigate up a few lines to the update method around line 42 and locate this line of code:

    movie_params = params.require(:movie).permit(:title, :description, :has_subtitles, :placement, :mpaa_rating, :release_date, :ticket_price, :runtime, :poster_image)

  4. Select this complete line and cut it (Cmd–X).

  5. Paste it into the private movie_params method:

    private
          def movie_params
          movie_params = params.require(:movie).permit(…)
       end
  6. Remove the variable assignment movie_params = so the method returns the parameters directly:

    private
          def movie_params
          params.require(:movie).permit(…)
       end
  7. Find the create method around line 26 and delete the identical movie_params line. From this point forward, when movie_params is invoked anywhere in the controller, Rails will automatically call our private method, eliminating code duplication.

  8. Our controller also contains unnecessary repetition with multiple instances of @movie = Movie.find(params[:id]). Let's create another private method to eliminate this duplication. Above the movie_params method, create a new private method:

    private
       def set_movie
    
       end
    
       def movie_params
  9. Locate the edit method around line 35:

    def edit
       @movie = Movie.find(params[:id])
    end
  10. Cut (Cmd–X) the @movie = Movie.find(params[:id]) line, leaving the method empty:

    def edit
    end
  11. Paste this code into the private set_movie method:

    private
       def set_movie
          @movie = Movie.find(params[:id])
       end

Advanced DRY Techniques

1

Private Methods

Extract repeated parameter handling into private movie_params method for controller-only access

2

Before Actions

Use before_action callback to automatically set @movie for show, edit, and update methods

3

Method Specification

Apply callbacks only to specific methods using the 'only' parameter with method name array

Controller Organization

Private methods differentiate helper functions from route-accessible actions. This separation follows Rails best practices and improves code security and maintainability.

Key Takeaways

1Strong parameters provide essential security by whitelisting expected form data and preventing unauthorized parameter injection
2Rails follows RESTful conventions with create methods for new records and update methods for existing record modifications
3Form helpers automatically populate edit forms with existing data when an instance variable contains a persisted object
4Partials eliminate code duplication by creating reusable view components that can be rendered from multiple templates
5Private controller methods organize non-action helper functions and improve code security through access restriction
6Before actions reduce repetition by automatically executing common setup code for specified controller methods
7Flash messages provide user feedback for successful operations and error handling through the application layout
8The DRY principle prevents maintenance issues and bugs by ensuring single sources of truth for repeated functionality

RELATED ARTICLES