Home > ruby on rails > Rails - Validating complex nested form

Rails - Validating complex nested form

February 10Hits:1
Advertisement

I have a form with four input fields where a user creates an item. In the form one of the four input fields is for picture which is used to create a user_item at the same time on form submission. I am running into several problems.

  1. When validation fails on the item I have the controller render :new but when this happens the picture input field is not visible.
  2. Validation on presence of picture is not working.
  3. I need a way to set the user_id attribute to current_user on the user_item when it is created.

item.rb

  validates :name, presence: true, uniqueness: true   validates :description, presence: true   has_many :tags   has_many :user_items   has_many :users, -> { uniq }, through: :user_items   belongs_to :user    accepts_nested_attributes_for :user_items   validates_associated :user_items 

user_item.rb

  belongs_to :user   belongs_to :item   mount_uploader :picture, PictureUploader   validates_presence_of :picture   validate :picture_size 

items_controller.rb

  def new     @item = Item.new     @item.user_items.build   end    def create     @item = item.new item_params      if @item.save       redirect_to items_path, notice: "Thank you for your item request!"     else       render :new     end   end    private      def item_params       params.require(:item).permit(:name, :description, :tag_list, user_items_attributes: [:picture]).merge(created_by: current_user.id)     end 

new.html.erb

<%= simple_form_for @item, html: { class: "create-item-form" } do |item_builder| %>   <div class="well">   <%= item_builder.input :name, required: false, error: false, label: "Item name" %>   <%= item_builder.input :description, as: :text, required: false, error: false, label: "Description of item" %>   <%= item_builder.input :tag_list, required: false, label: "Tags (these will help users find your item)" %>   <%= item_builder.simple_fields_for :user_items do |user_item_builder| %>     <%= user_item_builder.input :picture, as: :file, required: false, label: "Picture of you with this item" %>   <% end %>   </div>   <div class="clearfix">     <%= item_builder.submit 'Submit new item request', class: "btn btn-primary pull-right inherit-width" %>   </div> <% end %> 

Answers

I need a way to set the user_id

The simplest way to add the user_id to the user_item is to include a hidden_field in your fields_for. Not the most secure, but should work:

#app/views/items/new.html.erb
...
<%= item_builder.simple_fields_for :user_items do |user_item_builder| %>
    <%= user_item_builder.input :picture, as: :file, required: false, label: "Picture of you with this item" %>
    <%= user_item_builder.input :user_id, as: :hidden, input_html: { value: current_user.id } %>
<% end %>

#app/controllers/items_controller.rb
...
def item_params
   params.require(:item).permit(:name, :description, :tag_list, user_items_attributes: [:picture, :user_id]).merge(created_by: current_user.id)
end


the picture input field is not visible

According to this answer: Nested Input Disappears When Form Reloads, you need to rebuild your picture objects:

def create
   if @item.save
     ...
   else
     @item.user_items.build
     render :new
   end
end

file_field inputs are particularly interesting. Because your OS cannot guarantee your files will be exactly the same as they were, so the file_field is not populated.


Validation on presence of picture is not working.

You should use inverse_of to make sure the two objects can talk to each other:

#app/models/user.rb
class User < ActiveRecord::Base
  has_many :user_items, inverse_of: :user
end

#app/models/user_item.rb
class UserItem < ActiveRecord::Base
  belongs_to :user, inverse_of: :user_items
  validates :picture, presence: true
end



Update

If you wanted to pass the user_id through the backend, not having a hidden field, you'd be able to do something like this:

#app/controllers/items_controller.rb
class ItemsController < ApplicationController
  def new
    @user = current_user
    @user.user_items.build.build_item
  end

  def create
    @user = current_user.update user_params
  end 

  private

  def user_params
     params.require(:user).permit(user_items_attributes: [:picture, item_attributes: [:name, :description, :tag_list])
  end
end

This would have to be accompanied with the following change to your items#new view:

<%= simple_form_for @user, url: items_path, html: { class: "create-item-form" } do |f| %>
  <%= f.fields_for :user_items do |user_item_builder|
    <%= user_item_builder.input :picture, as: :file, required: false, label: "Picture of you with this item" %>
    <%= user_item_builder.fields_for :item do |item_builder| %>
        <%= item_builder.input :name, required: false, error: false, label: "Item name" %>
        <%= item_builder.input :description, as: :text, required: false, error: false, label: "Description of item" %>
        <%= item_builder.input :tag_list, required: false, label: "Tags (these will help users find your item)" %>
    <% end %>
  <% end %>
  <%= f.submit 'Submit new item request', class: "btn btn-primary pull-right inherit-width" %>
<% end %>

You'll also need to pass the attributes through the respective models:

#app/models/user.rb
class User < ActiveRecord::Base
  has_many :user_items
  has_many :items, through: :user_items

  accepts_nested_attributes_for :user_items
end

#app/models/user_item.rb
class UserItem < ActiveRecord::Base
  belongs_to :user
  belongs_to :item

  accepts_nested_attributes_for :item
end

Related Articles

  • Rails - Validating complex nested formFebruary 10

    I have a form with four input fields where a user creates an item. In the form one of the four input fields is for picture which is used to create a user_item at the same time on form submission. I am running into several problems. When validation fa

  • Rails validating API parametersOctober 25

    I wanted to keep my API request logic separate form the controller logic. I therefore make use of a separate model (EmailChecker) that creates an instance of this class via EmailChecker.new(params). Then I can check the new instance with valid?. When

  • Complex Rails Forms with Nested AttributesMarch 23

    Rails provides a powerful mechanism for easily creating rich forms called "nested attributes." It allows you to combine more than one model in your forms while keeping the same basic code pattern that you use with simple single model forms. In t

  • Rails 4: Complex forms and nested attributesFebruary 3

    I have a Rails 4 app where I have two related controllers, potential_client and location. I am trying to enable to creation of potential clients through the location controller. I believe there is something wrong with my form because it gets submitte

  • form validation with nested models in Rails

    form validation with nested models in RailsJanuary 22

    I have this problem. I need to validate the attributes of two models in the same form in Rails. One is the parent of the other. The form is like this: <%= semantic_form_for @professional do |pro| %> <%= pro.inputs :id => "information"

  • Rails scope with nested associationFebruary 17

    I'm trying to get to grips with rails scopes. I have the simple basics down but I'm trying to create a slightly more complex scope and I'm having some trouble. class Client has_many :referrals, through: :submissions has_one :address has_many :submiss

  • How to inplement a save-system for a complex nested list of character classs?August 1

    This is the situation I'm in: I'm developing a game with C# using unity. In the game I have characters which is either locked or unlocked, and they're pretty much the same. For every character, they have their respective rank, level, type and race (p

  • Drupal validation for nested field elementMarch 25

    I have written some custom validation for each element in a form. I use the following method to display errors. It automatically highlights the required fields. form_set_error('field_athletes_male', 'Athletes Male field is required.'); My problem is

  • Rails validation: Which method is preferredJune 16

    In Ruby on Rails there are two ways to validate, for instance, the presence of input fields. Say I want to make sure the user has filled out my fields called value and name. I could put in my model either: validates_presence_of :value, :name ## Or va

  • Rails validation regex not working: invalid though input correctJanuary 16

    I am trying to validate kind of a datetime field with a regex. The regex is correct - I tested it on rubular - but Rails throws an error on the field: invalid. In my model I have: validates :ddate, presence: true, format: { with: /\A(\d\d\.){2}\d{4}

  • Excel -complex nested formula to get previous 6 months status

    Excel -complex nested formula to get previous 6 months statusJanuary 18

    I have data with 2 columns named "Team" and "Lead Time%". Data is for 8 months. I need to calculate 3 months rolling average and compare the average numbers with the actual target. Step:1 Calculate average I did it using the below ment

  • Rails validation required parameter (lock_version)January 19

    I have a question about how can I validate a required change at rails model. for example: to the param lock_version we need the validate if this value always is present when tried to update the model. has rails some validation to test the change pres

  • Updating complex nested elasticsearch document using logstash and jdbcJanuary 19

    Let's assume that the Oracle Schema has following tables and columns: Country country_id; (Primary Key) country_name; Department department_id; (Primary Key) department_name; country_id; (Foreign key to Country:country_id) Employee employee_id; (Prim

  • What's the rails way of nesting routes with shared models?January 29

    I have following models: board.rb task.rb comment.rb Board has many comments, comment belongs to board. Task has many comments, comment belong to task. Board has many tasks, task belongs to board. What is the cleanest way of handling the routes? It c

  • Rails 4 testing nested resources with multiple URL paramsFebruary 1

    I have been at this for a few hours, still can't figure it out. I have 2 tests on 2 actions on a nested resources controller. requests is the parent resources route, and response is the nested resources route. These 2 tests give me a no route matches

  • Playa: Complex, nested and filteredFebruary 1

    EE 2.10.1 Playa 4.5.2 Stash 2.6.7 I'm building out a particularly complex single entry page and can't seem to wrap my head around how to approach what needs to be done. I have a Trips channel with two playa fields Related Outpost and Related Activity

  • rails with most nested models and cocoon gem;

    rails with most nested models and cocoon gem;February 16

    I have a rails4 app with nested model form. There is a product model that has_many product_features, has_many product_usecases and has_many product_competitors. Everything works fine except when I load the page only the first nested model (product_fe

  • rails validation regex August 7

    I don't really understand regular expressions. Can you explain them to me in an easy-to-follow manner? If there are any online tools or books, could you also link to them? --------------Solutions------------- The most important part is the concepts.

  • Rails validating with condition blockDecember 26

    Rails AR. validate one field, with 4 validators & 2 condition block validates :inn, presence: { if: -> { user.is_a?(Client) } }, inn: { if: -> { user.is_a?(Client) } }, uniqueness: { if: -> { user.is_a?(Client) } }, absence: { if: -> { use

  • Complex nested table in LATEX

    Complex nested table in LATEXOctober 7

    In my document I want to include nested tables as in the picture below. i- The table need to occupy the page width ii- The left most column "GRP1" & "GRP2" to be left aligned on the page iii- The column for aggregate percentage on

Copyright (C) 2017 ceus-now.com, All Rights Reserved. webmaster#ceus-now.com 14 q. 0.486 s.