Rendering form for new associated object in rails - ruby-on-rails

I am having trouble with creating association;
My models are Table and Columns (one table to many columns).
In my ColumnsController:
def new
#table = Table.find(params[:id])
#column = #table.columns.build
end
In my app/views/tables/show.html.erb:
<%= #table.name %></dd>
<%= render "columns/form" %>
In my app/views/columns/_form.html.erb:
<%= form_for #column, :url => {:action => :create, :id => #table.id }do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.button :submit%><% end %>
When I run it:
undefined method `model_name' for NilClass:Class
Extracted source (around line #1):
<%= form_for #column, :url => {:action => :create, :id => #table.id } do |f| %>
Why ? :-(

Try doing it with partials and local variables:
<%= render partial: "columns/form", locals: {table: #table, column: #column} %>
and
<%= form_for column, :url => {:action => :create, :id => table.id }do |f| %>
If you want it even simpler, you can do this:
<%= render partial: "columns/form", locals: {table: #table} %>
and
<%= form_for table.columns.new do |f| %>

Related

Rails 4 render partial for nested attributes without loop

Suppose I have a form like below
<%= form_for #uni, :html => {:multipart => true, :honeypot => true} do |uni_form| %>
<% 3.times { #uni.app.build } %>
<%= uni_form.fields_for :apps do |builder| %>
<%= render 'app', uni_form: builder %>
<% end %>
<% end %>
and my app partial is
<div>
<%= uni_form.label :uni_id, "University" %>
<%= uni_form.collection_select :uni_id, #unis, :id, :name, {:include_blank => true} %>
</div>
Now I want the first form code without the loop. Something like this
<%= form_for #uni, :html => {:multipart => true, :honeypot => true} do |uni_form| %>
<% 3.times { #uni.app.build } %>
<%= render 'app', uni_form: builder %>
<%= render 'app', uni_form: builder %>
<%= render 'app', uni_form: builder %>
<% end %>
How can I do this?
Firstly, don't build your associated objects in your view - do it in your controller:
#app/controllers/unis_controller.rb
class UnisConstroller < ApplicationController
def new
#uni = Uni.new
3.times do
#uni.apps.build
end
end
end
Secondly, the fields_for method is your friend here.
You'll gain what you need by using the following:
#app/views/unis/new.html.erb
<%= form_for #uni, :html => {:multipart => true, :honeypot => true} do |uni_form| %>
<%= uni_form.fields_for :apps do |builder| %>
<%= builder.label :uni_id, "University" %>
<%= builder.collection_select :uni_id, #unis, :id, :name, {:include_blank => true} %>
<% end %>
<% end %>
fields_for takes your model's associated objects and automatically creates the fields you need. There is literally no need to "loop" - fields_for does it for you... if you set it up correctly.
The problem you have is you're building your associated objects at runtime, which is not only inefficient & against convention, but I think it will prevent the form_for from recognizing them (which is what allows fields_for to loop through them).
The above code should fix this for you.

Rails: can't pass variable to partial, what am I doing wrong?

I'm trying a few different ways to define and pass the local variable to the partial, but it keeps saying it's undefined:
in Show file:
<% #startups.each do |startup| %>
<%= render :partial => "profile/startup" %>
<% end %>
in partial:
<%= simple_form_for [#commentable, #comment], :remote => true do |form| %>
<%= form.input :content, label: false, :input_html => { :id => "#{startup.user_id}" } %>
<%= form.submit "Submit" %>
<% end %>
These are the other ways I'm trying to pass the variable, but still getting undefined:
<%= render :partial => "user_comments/uac", object: startup, as: startup %>
<%= render :partial => "user_comments/uac", collection: startup, as: startup %>
<%= render :partial => "user_comments/uac", :locals => {:startup => startup} %>
Get rid of :partial. You haven't needed that in Rails for several versions.
The correct way of passing a local called startup to a partial is this:
render "profile/startup", startup: startup

Passing model id through rails route in form

I'm calling a custom action with simple_form. I'm having trouble passing the :id parameter to the action.
routes
post '/posts/:id/admin_vote' => 'posts#admin_vote', as: 'admin_vote'
form
<%= simple_form_for :post, url: admin_vote_path(:post_id), :html => {:class => 'form-inline admin-vote-form'} do |f| %>
<%= f.select :vote, 1..20 %>
<%= f.submit 'Vote', :class => 'btn btn-primary btn-xs' %>
<% end %>
partial render
<%= render 'layouts/admin_vote', :locals => { :post => post, :post_id => post.id } %>
For some reason the action receives params[:id] = 'post_id' instead of the actual id.
You're providing :post_id symbol to the admin_vote_path, so it uses that. Change it to:
admin_vote_path(params[:post_id])
or a different parameter depending on the context of your form.
it seems to me your form should be
<%= simple_form_for post, url: admin_vote_path, :html => {:class => 'form-inline admin-vote-form'} do |f| %>
<%= f.select :vote, 1..20 %>
<%= f.submit 'Vote', :class => 'btn btn-primary btn-xs' %>
<% end %>
you should build form based on variable post

Ruby on rails form_tag - sending model parameters to controller

Controller: #micropost = Micropost.new(params[:micropost])
But this form_tag is sending me params[:content] instead of params[:micropost][:content]
<%= form_tag( {:controller => :microposts, :action => :create}, :remote => true) do %>
<%= text_area_tag :content, "", :size=> "20x2" %>
...
...
...
<%= submit_tag "submit" %>
<% end %>
server:
Processing by MicropostsController#create as JS
Parameters: {"utf8"=>"✓", "content"=>"sdfsdf", "commit"=>"submit"}
You have to do either of the following
<%= text_area_tag "micropost[content]", "", :size=> "20x2" %>
OR
<%= form_for :micropost, :url=>{ :controller => :microposts, :action => :create}, :remote => true do |f| %>
<%= f.text_area :content, "", :size=> "20x2" %>
<% end %>
You have to avoid mixing form_for and input_tag.
When you declare a form_for #an_object do |form|, the best practice is to use form.text_area :content when :content is an attribute of your #an_object.
In this case, you can also write: text_area_tag "an_object[content]", but it's a little more dirty.

Ruby on Rails - How to pass hash parameter to a partial view?

'shared/subscription' %>
To call this partial view:
<% form_for(:subscription, :url => city_subscriptions_path(#city)) do |form| %>
<%= form.hidden_field :city_id, :value => #city.id %>
<%= form.text_field :email, :size => 30 %>
<%= form.submit "Email Me" %>
<% end %>
Since I am using this partial view on different places, how do I alter the caller so it will pass a hash for the form_for helper? So it would be like this when the helper is called:
<% form_for(:subscription, :url => city_subscriptions_path(#city), :html => {:id => 'main_input' }) do |form| %>
<%= form.hidden_field :city_id, :value => #city.id %>
<%= form.text_field :email, :size => 30 %>
<%= form.submit "Email Me" %>
<% end %>
<%= render :partial => "shared/subscription", :locals => {:foo => "bar", :foofoo => ["bar", "bar"]}
In your partial view, use them:
<%= foo #this outputs "bar" %>
<%= foofoo.to_s %>

Resources