I have a partial that I use to show errors from an object onto a form.
<% if object.errors.any? %>
<div id="error_explanation">
<h2>Oops, looks like <%= pluralize(object.errors.count, "error") %>
occured:</h2>
<br />
<ul>
<% object.errors.each do |key, msg| %>
<li><%=key%><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
It works great for 1 model.
However I can't figure out how to make it work for a form that has two models.
Any ideas? I don't want to use the plugin I would like to have more control.
Just output the partial for each model in the form view with 2 models and pass actual model instances into this partial as local variable:
<%= render :partial => 'name_of_partial_to_show_model_errors', :locals => {:object => #model1} %>
<%= render :partial => 'name_of_partial_to_show_model_errors', :locals => {:object => #model2} %>
Related
I have a Rails 3 application with a view that is irritating me. The view is essentially four tabs. Each tab shows a filtered list of records like this:
Tab One
<% #faults.each do |fault| %>
<%= fault.name %>
<% end %>
Tab Two
<% #faults_pending.each do |fault| %>
<%= fault.name %>
<% end %>
Tab Three
<% #faults_closed.each do |fault| %>
<%= fault.name %>
<% end %>
Obviously there is a lot more code that I have missed out. To tidy the view up significantly I considered making a partial for each tab, however, each of those partials would be identical except for the <% #faults.each do |fault| %> line.
Is there a way of having one partial and somehow when rendering the partial set the scope (or method, I can never remember what it's called).
I think you're looking for render's :locals option.
Tab one
<%= render :partial => "faults", :locals => { :faults => #faults } %>
Tab two
<%= render :partial => "faults", :locals => { :faults => #faults_pending } %>
Tab three
<%= render :partial => "faults", :locals => { :faults => #faults_closed } %>
Partial
<% faults.each do |fault| %>
<%= fault.name %>
<% end %>
I can't find how to display a dynamic label in Rails, i've tried using the :value => show_name property but it didn't work, it only displays Show name. Here is the view code
<p>
<div class="control-group">
<%= f.label :show_name, :value => :show_name, :class => 'control-label' %>
<%= #this next line fails with undefined method `show_name' for #<ActionView::Helpers::FormBuiler>
#f.label f.send :show_name, :class => 'control-label'
%>
<div class="controls">
<%= f.text_field :variable_value, :class => 'text_field' %>
<%= f.hidden_field :variable_id, :class => 'text_field' %>
<%= f.hidden_field :show_name, :class => 'text_field' %>
</div>
</div>
<p>
and if needed here is the show_name definition inside my model.
def show_name
Variable.find_by_id(self.variable_id).name
end
Ok, so i end up finding a solution that is very DRY, thank to this post. And the only thing im going to do is explain a lit bit more what to do:
First we are going to asume the most complex case in which we have nested forms and so we are using fields_for inside a form_for method:
<!-- f represents the form from `form_for` -->
<%= f.fields_for :nested_model do |builder| %>
<p>
<div class="control-group">
<!-- here we are just calling a helper method to get things DRY -->
<%= builder.label return_value_of_symbol(builder,:show_name), :class => 'control-label' %>
<div class="controls">
<%= builder.text_field :variable_value, :class => 'text_field' %>
<%= builder.hidden_field :variable_id, :class => 'text_field' %>
</div>
</div>
</p>
<% end %>
Note that we included the builder object(as specified in the fields_for call) in the parameters of our helper.
In our helper we define the return_value_of_symbol function
def return_value_of_symbol(obj,sym)
# And here is the magic, we need to call the object method of fields_for
# to obtain the reference of the object we are building for, then call the
# send function so we send a message with the actual value of the symbol
# and so we return that message to our view.
obj.object.send(sym)
end
Use label_tag, put the show_name on a instance variable on your controller and use like this:
<%= label_tag #show_name, nil, :class => 'control-label' %>
EDIT:
On your application_helper.rb, create a helper method similar to this one:
def show_name(name)
content_tag(:label, name, :class => 'control-label')
end
Then you can use the show_name(name) on your views like this:
<%= show_name(#name) %>
Just remember to populate the #name variable.
I am running into issues trying to separate a form from a view into a partial. I want to use the same form for the new and edit views. These are both on the same page. The new model form is at the top of the page and uses a variable that I set in the controller.
<%= form_for #new_hire do |f| %>
<%= render :partial => 'new_hire_requests/form', :locals => {:f => f} %>
<% end %>
I then have a partial for the pending approvals that gets rendered by another partial
<%= render :partial => 'pending_approval', :collection => #pending_approval %>
And inside the pending approval partial I have this
<%= form_for pending_approval do |f| %>
<%= render :partial => 'new_hire_requests/form', :locals => {:f => f} %>
<% end %>
This is throwing an error
undefined method `new_hire_request_path' for #<#<Class:0x0000010488ac98>:0x0000010223ffc0>
Is there a way to re use the form code for both a new and edit form on the same page?
Controller Logic
#new_hire = NewHireRequest.new
#new_hire_requests = current_user.new_hire_requests
#pending_approval = #new_hire_requests.select{|p| p.status == 'pending_hr_approval' || p.status == 'pending_exec_approval'}
Partial code
<%= render 'shared/error_messages', object: f.object %>
<fieldset class="first">
<%= f.label :first_name, "First Name" %>
<%= f.text_field :first_name %>
</fieldset>
<fieldset>
<%= f.label :last_name, "Last Name" %>
<%= f.text_field :last_name %>
</fieldset>
<%= f.submit "Submit for Approval <i class='icon-share-alt icon-white'></i>",
class: "button_green" %>
add resources new_hire_requests in the routes and get done with it .
I have a Post which can have multiple Tags, each of which relates to a User (think Facebook tagging).
In my Post form I have this Formtastic code:
<%= f.inputs :class => 'tags' do %>
<ul>
<%= f.semantic_fields_for :tags do |t| %>
<% if t.object.new_record? %>
<%= t.input :user_id, :label => " ", :input_html => { :class => 'chosen', :'data-placeholder' => 'Select connection' }, :as => :select, :collection => current_user.connections %>
<% end %>
<% end %>
</ul>
<% if #post.tags.present? && !#post.new_record? %>
<ul class="existing-tags">
<%= f.fields_for :tags do |t| %>
<% unless t.object.new_record? %>
<li>
<%= link_to avatar(t.object.user), user_path(t.object.user) %>
<%= t.check_box :_destroy %>
<%= t.label :_destroy, 'Remove' %>
</li>
<% end %>
<% end %>
</ul>
<% end %>
<% end %>
As you can see this can allow a tag to be added one at a time. However I'd like to allow multiple selections in the dropdown menu, to create multiple tags in one go. Adding "multiple" doesn't work, however: it simply results in creating a tag for the current user, posting the Post.
Can anyone suggest a way I can use a single select field to create multiple tags?
A bit late to the party, but I solved this problem using the awesome jQuery Chosen plugin which makes multiple selects look really good.
I got a undefined variable or method error when I try to render a partial view which is a form. The code like following:
in a partial view file, show.html.erb:
<ul class="users">
<% #users.each do |user| %>
<%= render 'pending' %>
<% end %>
</ul>
in _pending.html.erb:
<%= form_for current_user.friendships.build(:friendb_id => user.id) do |f| %>
<div><%= f.hidden_field :friendb_id %></div>
<div class="actions"><%= f.submit "Confirm" %></div>
<% end %>
The rspec error is:
undefined local variable or method `user'
I tried:
<%= render :partial => 'pending', :locals => {:user => user} %>
but it still doesn't work
Anyone knows why the form cannot find user variable?