0

I am tweaking "getting started" tutorial and trying to create an instance of a dependant model.

My models are Museum and Exhibition (Article and Comment in the tutorial).

The tutorial teaches how to create an instance of Comment when located in the Artcicle#show ERB file. This is achieved by using the following form helper:

<%= form_for([@article, @article.comments.build]) do |f| %>

I guess this form helper allows the form to access the Article Id and therefore allows accurate dependency.

I have managed to do that with my own models Museum and Exhibition.

Though I would like to be able to create an Exhibition instance without being located in the Museum#Show ERB file. But directly inside the Exhibition#New ERB file.

I have realised there was no route initially to do that, then have declared Exhibition as a proper ressource, on top of being dependant to Museum. Here my Routes file now :

resources :exhibitions

resources :museums

resources :museums do
   resources :exhibitions
end

which have created appropriate routes.

Though I am struggling with the Exhibition#New controller and ERB files.

Intuitively I understand I need to pass a list of all museums instances Ids and Names so that the user can choose to which Museum the exhibition belongs to.

But all my attempts to create the form helper have failed so far. My lastattempt was as such :

<%= form_for([@museum, @museum.exhibitions.build]) do |f| %>

<p>

  <%= f.select @museum.id, options_for_select(@museum.name) %>     </p>
....

with the following Exhibition controller bit :

def new
@museum = Museum.all
end
2
  • Please elaborate the specific problem regarding "Though I am struggling with the Exhibition#New controller and ERB files." Commented Jan 4, 2016 at 10:21
  • I am beginner regarding the form helpers and don't know how to create a form field that would allow me to select the Museum Id that could be passed to the Exhibition controller for creation of the Exhibition instance. Which is not required when creating this instance directly from the Museum#show action as the Museum Id is already available in the view in this case.. Commented Jan 4, 2016 at 10:27

2 Answers 2

1

You don't go for a nested form when creating the exibition in this case. Just provide a select tag with option for each museum.

controller:

def new
    @exibition = Exibition.new
end


view:
<%= form_for(@exibition) do |f| %>
    ...
    <%= f.collection_select(:museum_id, Museum.all, :id, :name) %>
Sign up to request clarification or add additional context in comments.

3 Comments

Many thanks. Exactly what I need. As my museum Model will have few instances (less than 1000) I recon the nested form may not necessary.. But it seems the hybrid way (Exhibition both as resources and nested resources) seems to work for now. I will stick to either or if I encounter issues.
A nested form is to add dependent objects while adding or updating a specific "parent" object and that's not your case.
Well the exhibiton shares the same detail as the parent venue: same location, same opening hours, can be destructed when parent is destructed... Only think would be a different entry price in case the exhibiton is accessible independently from the museum (temporary exhibition that doesnt need a ticket to permanent collections) ... not easy to find out actually. But I think I will keep the nesting route. (at least I know how to do both ways thanks to your form helper)
0

For your exhibitions#new which takes the route-path /museums/1/exhibitions/new (as an example), then:

def new
  puts params[:museum_id]
  # => 1

  @museum = Museum.find(params[:museum_id])
  @exhibition = Exhibition.new
end

Since @museum is now a Record object, then you could use the following in your exhibitions/new.html.erb

<%= form_for(@exhibition, url: museum_exhibitions_path(@museum)) do |f| %>

Take note that museum_exhibitions_path(@museum) translates to a path /museums/1/exhibitions in which...

  1. if it is a GET request, then it will be handled by controller-method exhibitions#index

  2. if it is a POST request, then it will be handled by controller-method exhibitions#create

Now, because form_for automatically uses POST request by default, then exhibitions#create, will be delegated to this route, which is what we wanted.

OR just use

<%= form_for([@museum, @exhibition]) do |f| %>

2 Comments

Thanks Jay, I have found a solution as per other answer. I recon I did something odd as declaring my Exhibition Model as a resources and a nested resources at the same time ... Will see..
Ohh i see, I do not think that's odd. I have both a resource and nested-resource for a Model as well in one of my projects, because I needed to filter new, create, edit, update, and destroy actions to have none-nested pathing. But also then filtered show, and index, to have nested pathing.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.