How to use Russian Doll caching on same model - ruby-on-rails-3

I am building a Rails 3.2 web app.
In this app I am using the russian doll style of caching.
I am fetching projects in a table list and records are cached. The problem is that
when I am for example changing the title of a record the title in the list is not updated.
If this were a association I would use :touch => true but it´s the same model.
This is how I start the listing:
<%= render #projects %>
This is the projects.html.erb template:
<% cache projects do %>
<%= render project %>
<% end %>
This is the project.html.erb template:
<% cache project do %>
<tr>
<td><%= link_to project.title.capitalize, admin_project_path(project) %></td>
<td><%= project.reference %></td>
<td><%= show_status project.status %></td>
</tr>
<% end %>
What am I doing wrong?
Thankful for all input.

Related

Grouping records with headings in Rails 3

I have an articles model in my Rails 3 application. The article model has a column called categories which is set using a select box in the new form view. (It's a select box because the options should never change and there are only four of them).
The index view code I have is as follows:
<% #articles.category.each do |article| %>
<%= article.category %>
<% #articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.author %></td>
<td><%= article.category %></td>
<td><%= link_to 'Show', article %></td>
<td><%= link_to 'Destroy', article, confirm: 'Are you sure?', method: :delete %></td>
</tr>
<% end %>
<% end %>
I have grouped by category in my controller:
#articles = Article.group(:category).order('title ASC')
However, this results in an exception which points to the following line <% #articles.category.each do |article| %>.
What is the tidiest (from within my view code) way of achieving the following:
Category 1
Article 1
Article 2
Category 2
Article 5
Category 3
Article 8
So each article is listed under it's category.
I'd suggest you to use group_by method (Documentation):
# in your controller
articles = Article.order('title ASC')
#grouped_articles = articles.group_by &:category
# in your view
<% #grouped_articles.each do |category, articles| %>
<%= category %>
<% articles.each do |a| %>
<tr>
<td><%= a.title %></td>
<td><%= a.author %></td>
<td><%= link_to 'Show', a %></td>
<td><%= link_to 'Destroy', a, confirm: 'Are you sure?', method: :delete %> </td>
</tr>
<% end %>
<% end %>

Rails - Rendering an edit form partial within another partial

I have a table that I am trying to make a bit more streamlined. In my view (this view is already a partial (_recipe_ingredient.html.erb), I have the following code, where rendering the partial is not working:
<tr>
<td><%= recipe_ingredient.ingredient.name %></td>
<td><%= recipe_ingredient.ingredient.weight1*recipe_ingredient.quantity %></td>
<td><%= recipe_ingredient.ingredient.description1 %></td>
<td><%= recipe_ingredient.quantity %></td>
<td><%= render(:partial => 'recipe_ingredients/edit', :locals =>
{:recipe_ingredient=> recipe_ingredient}) %></td>
<td><%= link_to 'Remove', recipe_ingredient, :confirm => 'Remove ingredient from
recipe?', :method => :delete %></td>
</tr>
Previously, I was using link_to to edit the recipe_ingredient as follows (which worked fine), but I would like not to have the user go to another page to edit - instead I want the form to be part of the table:
<td><%= link_to 'Edit Quantity', edit_recipe_ingredient_path(recipe_ingredient) %></td>
The edit partial (which the new non-working code calls) looks like:
<h1>Editing recipe_ingredient</h1>
<%= render 'recipe_ingredients/form', :recipe_ingredient => #recipe_ingredient %>
And the standard form partial looks like:
<%= form_for(#recipe_ingredient) do |recipe_ingredient| %>
<% if #recipe_ingredient.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#recipe_ingredient.errors.count, "error") %> prohibited this
recipe_ingredient from being saved:</h2>
<ul>
<% #recipe_ingredient.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= recipe_ingredient.label :quantity %><br />
<%= recipe_ingredient.number_field :quantity %>
</div>
<div class="actions">
<%= recipe_ingredient.submit %>
</div>
<% end %>
Mainly, I'm confused why it works using link_to, but I can't simply render the partial. The error I'm getting is undefined method `model_name' for NilClass:Class in the first line of the form partial.
I've tried taking the "#" off #recipe_ingredient in the form partial, but that doesn't work either.
Thanks in advance for any help.
just create object with #recipe_ingredient in your action i think its an edit action.
#recipe_ingredient = RecipeIngredient.find_by_id(params[:id)
hope this will work fine.

rails 3 with a ajax created form

I want to create a page which user can modify data on that page.
So I tried to use a ajax call to replace the original data table row into a form.
The new form could be created and replace the row by my code currently. But after edited data in that form and click 'Update', nothing happened. In my console shows something like:
ActionController::RoutingError (No route matches "/projects/5"):
I can't figure out why it didn't work.
Codes are shown as following:
index.html.erb
<tr>
<th>Name</th>
<th></th>
<th></th>
</tr>
<% #projects.each do |project| %>
<tr id="project_<%= project.id %>">
<td><%= link_to project.name, project %></td>
<td><%= link_to 'Edit', edit_project_path(project), :method => :get, :remote => true %></td>
<td><%= link_to 'Destroy', project, :confirm => 'Are you sure?', :method => :delete , :remote => true %></td>
</tr>
<% end %>
edit.js.erb
$('#project_<%= #project.id%>').replaceWith("<%= escape_javascript(render :partial=>'edit') %>");
_edit.html.erb
<tr id="project_<%= #project.id%>">
<%= form_for(#project, :remote => true) do |f| %>
<%= form_authenticity_token %>
<td><%= f.text_field :name %></td>
<td><%= f.submit 'Update' %></td>
<td><%= link_to 'Destroy', #project, :confirm => 'Are you sure?', :method => :delete , :remote => true %></td>
<% end %>
</tr>
Routing errors are usually caused by one of the following:
you don't have the route specified in routes.rb. Run "rake routes" at the command line and see if something like "/projects/:id" shows up. If not you have to add the route by adding a projects resource or otherwise specifying the route manually. Make sure the HTTP method matches the HTTP verb specified in routes.rb.
you have no controller named named ProjectsController or no create method (if your ajax method is posting) or no update method (if its putting).

Ruby on Rails Rendering tables with dynamic content and partials

I've used this site plenty of times to find my answer but im am unfortunately stuck now and need some help. On my main content page I am working on im running into an issue with creating a tables using CSS and div ids.
Overview
The table is compromised of 2 rows and 6 columns and then spilt into 12 boxes which each box 200px X 200px. Now the content of each box contains a new item (#books) which is generated from a separate controller(used the built in generate scaffold command). I am also using pagination to limit the items on the page (12) so older items just roll on back.
Issue
I am able to populate each of the 12 boxes with new content by using the following code on my controller and view
controller
def content
#books= Book.paginate(:page => params[:page], :per_page => 12)
respond_to do |format|
format.html # content.html.erb
end
view {content.html.erb}
<% #books.each do |book| %>
<div id="column1">
<tr>
<td><%= book.name %></td>
<td><%= book.title %></td>
<td><%= book.content %></td>
<td><%= link_to 'Show', book %></td>
</tr>
</div>
<% end %>
<br />
<div id="paginate">
<%= will_paginate(#books,
) %)
</div>
</div>
What happens when I generate the view is that everything is rendering perfectly but all of my books are using the same 'column 1'
<div id="column1">
<tr>
<td>Title</td>
<td>Name</td>
<td>Content</td>
<td>Show</td>
</tr>
</div>
<div id="column1">
<tr>
<td>Title </td>
<td>Name</td>
<td>Content</td>
<td>Show</td>
</tr>
</div>
I would like for each book to have its own column {2, 3,4,...12} so i can target each individually if i need to using jquery. The other problem is that i would like to use render partial for everything in the but when i use the render partial it places all the items within the 1 column {relisting of Book.all }so it just repeats all the contained information. I have a feeling im suppose to use another method or edit the current one to complete this but I'm unsure what goes were. Thanks!
greenz
Update
Hey Mike i really appreciate your effort in trying to explain to a newby whats going on. I basically went back to step one a applied each piece of code to see where it is going bonkers at. You are doing a wonderful job explaining the issue yet i can't grasp whats going on when rendering the code because the ruby doc's for rendering and layout are pretty basic and dont have any examples where i can see how div_for tag effects the rendering process (I'm a visual person). I wanted to show you the new code but comments don't allow it so i opened an answer :(
The first edit was removing the
<% #books.each do |book| %>
and replacing with
<table>
render #books
</table>
so now my code looks like this {content.html.erb}
<div id="maincontent">
<table>
render #books
</table>
<div id ="column1">
<tr>
<td><%= book.name %></td>
<td><%= book.title %></td>
<td><%= book.content %></td>
<td><%= link_to 'Show', book %></td>
</tr>
</div>
<% end %>
<br />
<div id="paginate">
<%= will_paginate(#books,
) %>
</div>
</div>
When this is applied i receive an unexpected end error when rendering the view pointing to the last line of my code.(When adding the end tag to the end it just threw another error) So i then changed the render page from _bookcontent.html.erb to _book.erb and inserted the partial between the column1 div as shown.
<div id ="column1">
<%= render :partial => "book" %>
</div>
<% end %>
I understand what this tag is now doing it telling my partial that for every "book" render the latest book id from the database. So now the render #books statement is keeping track of the books id for every render page i insert. (I could be mistaken but this is how i perceive it). So now onto the infamous
_book.erb that this page is rendering here is my code.
<% div_for(book) do %>
<tr>
<td><%= book.name %></td>
<td><%= book.title %></td>
<td><%= book.content %></td>
<td><%= link_to 'Show', book %></td>
</tr>
<% end %>
From my reading on the <% div_for(book) do %> is wrapping a unique div id around each book such as
<div id="book_123"> Book.name / Book.Title </div>
This div is now contained inside my column1 div ID from before which has all my styling for my column/boxes. From the lack of information on the div_for tag I am still running into errors and unexpected ends in my code. (Trying to debug the _book.erb with ruby -w doesn't work so i dont know how to use the end tags). These are the take aways i am trying to correct for my sanity.
Should I remove the <div id="column1"> from my content page and apply a new div id / class elsewhere on my content page?
Where do i insert <% end %> tags one in the partial and in my content.html.erb before my pagination? It seems as though when i have both the renderer complains about unexpected ends at the end of each page.
When substituting your code in place of mines i receive the above unexpected end but this isn't due to you im definitely missing a component in my code.
I could be approaching this the wrong way from a layout perceptive in the first place but my main goal is to have 2 rows of 6 boxes/columns w/ each box containing a different book. Then using pagination to scroll back to the earlier books and apply the same layout which it does fine now but i am using the same column id for each book and need to target all the boxes separately.
If I understand you correctly, this is just a case of it doing what you said, not what you meant.
Whatever controller has the content method should look like this:
def content
#books = Book.paginate :page => params[:page], :per_page => 50
end
Your view should look like this(old syntax but still should work fine).
content.html.erb:
<div id="maincontent">
<table>
<%= render :partial => 'book', :collection => #books %>
</table>
<br />
<%= will_paginate #books %>
</div>
Or try the new syntax. The new syntax is weird and I haven't tried it personally but I think this should work. So here is the alternate, more Rails 3 version of content.html.erb:
<div id="maincontent">
<table>
<%= render #books %>
</table>
<br />
<%= will_paginate #books %>
</div>
I think it chooses the partial based on the class name and whether it is enumerable.
The _book.html.erb partial:
<%= div_for(book) do %>
<tr>
<td><%= book.name %></td>
<td><%= book.title %></td>
<td><%= book.content %></td>
<td><%= link_to 'Show', video %></td>
</tr>
<% end %>
Div_for is the secret sauce.
The only end that is required is the one inside the partial to close the block opened when we called do after the div_for.
Now i am getting unexpected end errors when i render the page here is my view
view = content.html.erb
<div id="maincontent">
render #books
<div id="column1">
<tr>
<%= render :partial => "bookcontent" %>
</tr>
</div>
<% end %>
<br />
<div id="paginate">
<%= will_paginate(#books,
) %>
</div>
</div>
Here is my render partial = _bookcontent.html.erb
<% div_for(book) %>
<tr>
<h3><%= book.name %></h3>
<h3><%= book.title %></h3>
<h3><%= book.content %></h3>
<h3><%= link_to 'Show', book %></h3>
</tr>
<% end %>
I am also clueless as to if i should be using a div id or class. By default i always use just an id.
If I understand correctly, your code is working fine but you want to have:
column1
column2
column3
...
for each book. If that is the case, why don't you simply replace:
<div id="column1">
with
<div id="column#{#book.id}">
or use a counter
<%
book_counter=0
#books.each do |book|
book_counter = book_counter+1
%>
<div id="column#{book_counter.to_s}">

Getting current_user error when using Ryan Bates' CanCan authorization plugin

The portion of the view that is applicable:
<% #projects.each do |project| %>
<tr>
<td><%= project.name %></td>
<td><%= project.description %></td>
<td><%= link_to 'Show', project %></td>
<% if can? :update, #project %>
<td><%= link_to 'Edit', edit_project_path(project) %></td>
<% end %>
<% if can? :destroy, #project %>
<td><%= link_to 'Destroy', project, :confirm => 'Are you sure?', :method => :delete %></td>
<% end %>
</tr>
<% end %>
models/ability.rb
class Ability
include CanCan::Ability
def initialize(designer)
can :read, :all
end
end
This is the error I get:
NameError in Projects#index
undefined local variable or method `current_user' for #<ProjectsController:0x000001016d62d8>
Extracted source (around line #18):
15: <td><%= project.description %></td>
16: <td><%= link_to 'Show', project %></td>
17:
18: <% if can? :update, #project %>
19: <td><%= link_to 'Edit', edit_project_path(project) %></td>
20: <% end %>
21:
Thoughts?
I had errors in my AuthLogic install. Or rather, not errors, but when I installed it I used current_designer (which was the main user I was concentrating on) rather than current_user.
It seems CanCan didn't like that.
So I am now in the process of re-doing all my user models. But so far, it seems to have fixed this issue.