Separating Ruby Code which requires a block with Partials - ruby

I want to use
<% form_tag ( <<variables from partial here>> ) do %>
on a partial; problem is on the IDE it already is trying to tell me I have invalid code; this is because the "DO" is to be paired with an "END". I cannot end on the partial itself; because there is some content after the "DO" which is on the page where the partial is called.
How do I use the form_tag in the partial while using the content I have from the page which called the partial?

Sounds like you're in a very sticky situation. This is what I think you've got from your description:
#partial_1
<% form_tag (:model_name) do %>
#partial_2
<% form_contents %>
<% end %>
#controller
#model = Model.load
render(partial1 << partial2)
You may have to correct me if I'm wrong, but is it possible instead to do this?
#controller
#model = Model.load
render(partial_1)
#partial_1
<% form_tag ... %>
<% render(partial_2) %>
<% end %>
#partial_2
<% all the form guts %>
If you're using straight ruby you're probably using the ERB library and you are binding every time, which should keep the variables live all the way through.

Related

How to dry code?

I am working with has many through association in Application.
I access email from employee table in INDEX action of InventoryController like below code:
<% #inventories.each do |inventory| %>
<% inventory.employee_inventories.each do |e| %>
<%if e[:status]== 'ALLOTED'%>
<%= e.employee.email%>
<% end %>
<% end %>
<% end %>
Please help me How to DRY this code in view? Thanks in advance
#alloted_emails = #inventories.flat_map(&:employee_inventories).select do |i|
i[:status] == 'ALLOTED'
end.map do |i|
i.employee.email
end
Unless you want to create a scope as suggested by #Pavan, just introduce this var and use it.
If you are using the same code in different views then you can create a helper.
Otherwise write down this code like-
<% #inventories.each do |inventory| %>
<% inventory.employee_inventories.each do |e| %>
<%= e.employee.email if e[:status]== 'ALLOTED' %>
<% end %>
<% end %>
The main problem in your code is n+1 query problem. If you are using eager loading then there is no issue otherwise use eager loading using includes keyword in your query.

Clarification on accessing methods

I am having trouble accessing a method i have written in a class, the problem is im trying to access it within an instance of that class, but would appreciate someone explain in a bit more details as to why this doesn't work and things to look at to get a solution.
I have created a simple helper method to use in my view to join two attributes
class TeamMember < ActiveRecord::Base
def fullname
"#{self.forename} #{self.surname}"
end
end
Within my view (show action) I want to be able to use this method
def show
#team_member = TeamMember.find(params[:id])
end
So doing this for example gives me an undefined method
<%= link_to fullname(#team_member) %>
OR
<% #team_member.each do |t| %>
<%= link_to fullname, t %>
<% end %>
Whereas this works
<% #team_member.each do |t| %>
<%= link_to "#{t.forename} #{t.surname}", t %>
<% end %>
Could someone help to clarify this for me so that i can learn from it please
You defined fullname method in your TeamMember class, but you try to call this method with implicit receiver in view, which is ActionView::Base instance. Instead, you should use explicit receiver, which must be TeamMember instance:
<%= link_to #team_member.fullname, #team_member %>
and:
<%= link_to t.fullname, t %>

Ruby render another controller partial

I have a controller and in the index view i am trying to render a partial from another controller. Here is the other controller:
class ModelController < ApplicationController
def view
#model = Model.where('equipment_id' => params[:equipment_id])
render :partial => 'view_model'
end
end
And in the index view I am trying this:
<div id ="mdl-inner_box" class="inner_box">
<%= render "model/view", :#model => Model.first %>
</div>
And my partial view is this:
<% #model.each do |m| %>
<div> <%= m.name %> </div>
<% end %>
I am getting this error:
ActionView::MissingTemplate at /equipment
Missing partial model/view with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :b
What is the correct way to do this?
Thanks
There are too many errors to really address this question!
First of all if you are showing code for your index action, why is it the view action?
I have a controller and in the index view...
class ModelController < ApplicationController
def view
# should be
def index
In your index view, presumably app/views/models/index.html.erb you render a partial, which points to app/views/model/_view.html.erb. That should probably be models
<%= render "model/view", :#model => Model.first %>
<!-- should be -->
<%= render "models/view", :model => #model %>
And set #model in your controller. You can put Model.first into the view itself, but I think that breaks MVC pattern a little bit.
Finally in the partial, you access the class variable #model defeating the purpose of passing it as a local. You also call .each on it, which is a method for looping through collections, not for individual records. For example you would do #models.each and never #model.each.
<% #model.each do |m| %>
<div><%= m.name %></div>
<% end %>
<!-- should be something like -->
<%= model.name %>
Long story short, seems to me you're pretty lost, so I would start with a good book about Ruby on Rails before you continue. Here's a free one: http://ruby.railstutorial.org/ruby-on-rails-tutorial-book?version=4.0

rails change path of partial collection rendering

I have an STI relationship where a conversation is composed of both messages and images.
Now when I go to render them i use:
<%= render conversation %>
which works perfect. It finds the given template for the given object and renders it.
Now for my mobile site I want to use the same thing only now it should find say:
/mobile/message/_message.html.erb
instead of
/message/_message.html.erb
So in my controller i said:
if mobile?
prepend_view_path "mobile"
end
Which does get called, and it "prepends my view path" which i can see is working when i do:
raise view_paths.inspect
However now when i do my
<%= render conversation %>
It is still looking in the default location i.e. /views/ for the partial
Well, this should work, but it is distressingly inelegant:
<% conversation.each do |c| %>
<% c_class = c.class.to_s.downcase.underscore %>
<%= render :partial => "mobile/#{c_class}/#{c_class}", :object => c %>
<% end %>

ruby on rails 3.1 fragment caching

I have an app and I'd like to cache some parts of the page, and I have been reading a lot about the ways to do this.
I understand that fragment caching is the best way to do it on my project, but I canĀ“t find a simple example to learn how to implement this.
I would like to use the fragment cache with autoexpire.
<% cache(:action => 'recent', :action_suffix => 'all_products') do %>
All available products:
<% Product.all.each do |p| %>
<%= link_to p.name, product_url(p) %>
<% end %>
<% end %>
Where do I set the autoexpire? any examples around? how can I do this?
In your product model you can do something like this
after_save :expire_caches
after_destroy :expire_caches
# can't do this in a sweeper since there isn't a controller involved
def expire_caches
ActionController::Base.cache_store.delete_matched(%r{product\?for=\d+&fragment=products})

Resources