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

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

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.

Rendering form for new associated object in 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| %>

Cant pass local object to nested partial in Rails 3

Im hoping that someone can shed light on what is probably a simple mistake. Im trying to pass a local variable, article, which is in the partial _article.html.erb, to another partial nested within _article.html.erb. When the partial code is in _article.html.erb, it works fine.I've tried many variations (including :locals) but cant seem to pass the local variable.
_article.html.erb
<% if current_user.favorited?(article) %>
<%= render :partial => 'unfavorite', :object => article %>
<% else %>
<%= render :partial => 'favorite', :object => article %>
<% end %>
_favorite.html.erb (both favorite and unfavorite are more or less the same, so I've only posted one)
<%= form_for current_user.favorites.find_by_article_id(article), :html => { :method => :delete, :class => 'unfavorite_form', }, :remote => true do |f| %>
<div><%= f.hidden_field :article_id %></div>
<%= image_submit_tag("vote-favorite-on.png", :alt => "Favorite", :id => "favorites_button", :title => "Remove from favorites") %>
<% end %>
The error message is:
undefined local variable or method `article' for #<#<Class:0x491c2b0>:0x6727a58>
The rails docs for rendering mention the use of object like this:
<%= render :partial => "customer", :object => #new_customer %>
And say that:
Within the customer partial, the customer variable will refer to #new_customer from the parent view.
Which makes it seem like the :object variable is translated into the name of the partial. So in your case, in _favorite, you'd have to use the favorite variable:
<%= form_for current_user.favorites.find_by_article_id(favorite), :html => { :method => :delete, :class => 'unfavorite_form', }, :remote => true do |f| %>
Personally I prefer the locals syntax, because then you can be explicit:
<%= render :partial => 'favorite', :locals => {:article => article} %>

Form for array element in partial

I'm making a project for which I have a class online_score which has as one of its attributes an array called url of online_score_url objects. What I did up to now is the following.
views/online_score/new:
<div class="urlInput">
<% f.fields_for :url do |b| %>
<%= render "online_score_url_fields", :f => b %>
<% end %>
<%= add_url_link "Add Another link", f %>
</div>
views/online_score/_online_score_url_fields:
<div class="inputset">
<%= f.label :url %> <%= f.url_field :url, :value => "http://www.google.be"%>
<%= f.label :description %> <%= f.text_field :description %>
<%= link_to_remove_fields "remove", f %>
</div>
My problem is now that I want to be able to dynamically add inputs for online_score_urlobjects which I try to do with JQuery. I try to do this by rendering the partial like so:
helpers/online_scores_helper.rb:
def add_url_link(name, form)
link_to_function name do |page|
online_score_url = render(:partial => 'online_score_url_fields', :f => form )
page << %{
$('.links').append("#{ escape_javascript online_score_url }");
}
end
end
The problem is then that fseems to be undefined in the partial. I expect this has something to do with the line <% f.fields_for :url do |b| %> in my view which doesn't get executed via the dynamic adding. But I don't really know how to fix. I think I need an alternative for the form_formethod? How to do that?
I guess my main question is: how do I iterate over an array in a controlled way, and for every element create a set of input forms like in the partial AND be able to 'add' one or more dynamically?
Thanks for your time.
Try this one:
<%= render "online_score_url_fields", :locals => {:f => b} %>
this is beacuse :f is not a parameter for the render method. So you need to use :object, :collection or something locals with the syntax above.
The same here:
online_score_url = render(:partial => 'online_score_url_fields', :locals => {:f => form} )

In Rails 3, is form_for supposed automatically know when a model's named helpers are overridden?

In my routes file I have:
resources :features, :as => 'featured'
However, when I use the following:
<% form_for #feature, :html => { :multipart => true } do |f| -%>
<%= render :partial => "form", :locals => { :f => f } -%>
<p><%= submit_tag "Feature these submissions" -%></p>
<% end -%>
I receive this error:
"undefined method `features_path' for #<#:0x00000106228ec0>"
This is my "new" method in the "features_controller":
def new
#feature = Feature.new
#submissions = Submission.find(pending_featured_submissions)
end
Before I upgraded to Rails 3, Rails was able to figure out that I was using a custom named helper. Now it seems as though form_for is ignoring the line in my resources file and using features_path, when it should be used featured_path.
Maybe I'm doing something wrong, or missing something.
Thanks for looking =)
For what its worth I ended up having to specify the url in the form builder.
<% form_for #feature, :url => featured_index_path, :html => { :multipart => true } do |f| %>
You are using submit_tag. If you used the form object to submit then your path will be as defined in the form_for so instead of
<% form_for #feature, :html => { :multipart => true } do |f| -%>
<%= render :partial => "form", :locals => { :f => f } -%>
<p><%= submit_tag "Feature these submissions" -%></p>
<% end -%>
you should use
<%= form_for #feature, :html => { :multipart => true } do |f| -%> //Note the = sign
<%= render :partial => "form", :locals => { :f => f } -%>
<p><%= f.submit "Feature these submissions" -%></p>
<% end -%>
Note that because you are in Rails 3 not Rails 2, you should use the = symbol in your form declaration

Resources