Derek
Derek

Reputation: 12388

Rails form_for multiple different class objects?

Is there a way to have multiple and different models in one form_for in rails 4?

maybe something like

# gives error
<%= form_for ([@user, @pet]), url: some_path do |u, p| %>

Upvotes: 2

Views: 2367

Answers (2)

kobaltz
kobaltz

Reputation: 7070

Typically something like this is done with associations of the two models. In which case, I will take a few assumptions here. I assume that you have two models user and pet. I assume that a pet belongs to a user and a user can have many pets. With this kind of association, a pet model would have a user_id attribute that would association the user to that pet.

User Model

attr_accessible :name, :pets_attributes
has_many :pets
accepts_nested_attributes_for :pets

Pet Model

attr_accesible :user_id, :name
belongs_to :user

Personally, I am a big fan of using simple_form as it has a cool association feature.

View

<% simple_form_for @user do |f| %>
  <%= f.input :name %>
  <%= f.simple_fields_for :pets do |p| %>
    <% p.input :name %>
  <% end %>
<% end %>

Controller

Within your controller, (going to assume that this is a new action). This will create a line for the user and build three spots for the pets.

def new
  @user = User.new
  3.times do
    @user.pets.build
  end
end

Routes

One thing that you may want to consider with the routes is to set them up similar to this. This would create your routes to be a bit prettier as a Pet show action would also be referenced to the user /users/:user_id/pets/:pet_id

resources :users do
  resources :pets
end

Upvotes: 3

Featalion
Featalion

Reputation: 657

It is not possible with form_for helper because it takes only one record. Syntax with [@user, @pet] is for building right routes for associated records. Only last element of passed array will be used as record. Other will be used to create right routes. So, in your example, assuming user has one or many pets and @user is persisted, result route will look like one of the following:

"user/#{@user[:id]}/pet/#{@pet[:id]}" # when @pet is persisted
"user/#{@user[:id]}/pet/new" # if @pet = Pet.new

You can define your own helper and form builder or just write custom template view to accept multiple records.

Upvotes: 1

Related Questions