Try to modify the "Todo app" - ruby-on-rails

I'm starting on ruby on rails, first thing I want to try is modifying the "Todo app" example.
I do this by the tutorial: https://www.youtube.com/watch?v=fd1Vn-Wvy2w
After I finished, I saw that when I clicked on a todo_list, it will redirect to "show" form todo_list, but now I want the "show" display on the index with all the todo_list. I have tried to write
<%= todo_items.content %>
on the index page but it got some errors. Is there any solution or should I modify something on the Controller page so that
todo_items.content
should be able to display on the Index page

You need to load those items in your controller action first:
def index
#todo_items = TodoItem.all
end
then in index.html or whatever template you are rendering for this action you can render this collection:
<%= render #todo_items %>
that should render an todo_item partial that you should have created based on your video located at /app/views/todo_items/_todo_item.html.erb. Or you can do:
<% #todo_items.each do |item| %>
<%= item.content %>
<% end %>
In controller:
def index
#todo_lists = TodoList.all
end
in view:
<% #todo_lists.each_with_index do |list, index| %>
List <%= index + 1 %> todos:
<%= render list.todo_items %>
<% end %>

Related

Ruby on Rails if/unless statment for AJAX destroy when cart is empty

I am building webstore. I added a bit of AJAX functionality to add, update and remove items from my cart without refreshing.
It works perfect as long as there are no items in a cart and render cart_empty partial properly.
The problem is when I add few items, and I can update/remove them without refreshing and
finally I remove the last one, and it do not switch to the cart_empty partial and there are only empty table headers left from cart-items partial.
Can I add some logic to destroy.js.erb?
destroy.js.erb
$("#cart-item").html("<%= j render 'carts/cart_items' %>");
the show.html.erb contains this unless function:
<% unless current_order.order_items.empty? %>
<div id="cart-item">
<%= render 'cart_items' %>
</div>
<% else %>
<div id="cart-empty">
<%= render 'cart_empty' %>
</div>
<% end %>
Maybe should I modify somehow my controller to check if there are order_items in a current_order?
Thank you!
A JS.erb template is evaluated in exactly the same way as a HTML template. So you can just add a condition:
<% if current_order.order_items.any? %>
$("#cart-item").html("<%= j render 'carts/cart_items' %>");
<% else %>
$("#cart-item").html("<%= j render 'carts/cart_empty' %>");
<% end %>
None that this implies that current_order is either a helper or a local passes to the view.
But you might want to refactor this and push the condition down to the partial:
# carts/cart_items.html.erb
<% if cart_items.none? %>
<% render :cart_empty %>
<% else %>
# ...
<% end %>
Which will let you just write:
<%= render 'carts/cart_items', cart_items: current_order.order_items %>
See:
Layouts and Rendering in Rails - passing local variables

Rails 5 ActionView::Helpers capture method

I'm new in ruby on rails, and I want to practice it.
I'm stuck when I want to include a view into antoher view.
I want by doing that to have my posts into another view than of posts/index
posts/index
method:
def index
#Posts = Post.all
end
view:
<% #posts = capture do %>
<% #posts.each do |post| %>
<h3>
<%= post.title %>
</h3>
<p>
<%= post.content %>
</p>
<% end %>
<% end %>
pages/index
<h1> Index Of another pages </h1>
<%= #posts %>
If you want to force your index action to render another view, then go with follow code:
def index
#Posts = Post.all
render 'pages/index'
end
Correct me if I haven't get you
It sounds to me like you need to save the reusable view code as a partial, and render it all places it's required.
To use a partial, save it down with an underscore prefix, i.e. _posts.html.erb.
This can then be rendered using:
<%= render 'path/to/posts' %>
You'll likely need to pass in the posts variable to the partial, as in the following:
<%= render 'path/to/posts', posts: #posts %>
And the change your view to use posts rather than #posts.
Update:
The result of capture is assigned to #posts, although this variable still wouldn't be available in another template - rather to be used again on the same page
Based on what you're saying about the project's structure, it sounds like you'd need the following:
in app/views/posts/_posts.html.web
<% #posts.each do |post| %>
<h3>
<%= post.title %>
</h3>
<p>
<%= post.content %>
</p>
<% end %>
In both controllers' index action:
#posts = Post.all
In the posts/index view:
<%= render 'posts' %>
In the pages/index view:
<%= render 'posts/posts' %>
I don't want to confuse things, but Rails has a little magic in there where -
alternatively - you can define a partial _post.html.erb as follows:
<h3>
<%= post.title %>
</h3>
<p>
<%= post.content %>
</p>
And simply call <%= render #posts %> in each view. This would be the best 'Railsy' way of doing things.
Let me know how you get on!

Index page rendering the entire Event object. - Rails

I have started a new app and I'm setting up all the basic CRUD operations. I have a Event table and I'm trying to render all the events to an index page. All I want to render is the event name and description. Right now the name and description render but so does the entire event object? That's strange to me because I'm going through each object a picking out what I want to display. I'll show my code for clarity.
VIEW:
<%= #event.each do |e| %>
<%= e.name %>
<%= e.description %>
<% end %>
CONTROLLER:
class EventsController < ApplicationController
def index
#event = Event.all
end
end
SCREENSHOT:
FYI: I'm using the rails_admin gem. Any ideas on why the entire object is rendering would be greate thanks!
You have syntax error
Just remove the <%= from your first line and only <% then problem solved.
Now you should have:
<% #event.each do |e| %>
<%= e.name %>
<%= e.description %>
<% end %>
Meaning of <%= is to print and you printed entire object.

Rails: how to communicate view controller in AJAX?

The case is when user click an add link, if the url already added, there will be a alert otherwise will display a form to add new bookmark. The code below works quite well for checking the duplicated url, but if the url is not duplicated I just don't know how to render a add bookmark (in this case the page will be loaded like a normal non ajax request)
This is the link in view
<%= link_to "add", user_bookmark_add_path(current_user, bookmark), remote: true %>
The link will invoke the controller action add
# controllers/bookmarks_controller.rb
def add
#bookmark = Bookmark.find(params[:bookmark_id])
respond_to do |format|
format.js
end
end
The javascript file
# views/bookmarks/add.js.erb
<% if duplicated_url? #bookmark.url %>
alert("Duplicated")
<% else %>
# how to render the new bookmark form here
<% end %>
Any suggestion ? Thanks
Create a partial for new bookmark form.
_form.html.erb
<%= form_for(bookmark) do |f| %>
<%= f.text_field :name %>
<%= f.submit "submit" %>
<% end %>
Add id to your link
.html.erb
<%= link_to "add", user_bookmark_add_path(current_user, bookmark), remote: true, id: "bookmark" %>
Replace your link with partial.
.js.erb
<% if duplicated_url? #bookmark.url %>
alert("Duplicated")
<% else %>
$("#bookmark").replaceWith("<%= j render "form", bookmark: Bookmark.new %>");
<% end %>
On your add.js.erb file, in the else part of the code you can append a partial to your list like this:
$('#your_list').append(
"<%= escape_javascript(render('your_item_of_the_table_partial')) %>"
);
This partial can be a list item, a table row, a div with your content, anything. The thing is, you will need a chunk of html to be re-rendered on your screen with the new content.
Example of a list item partial:
# _bookmark_item.html.erb
<li><%= #bookmark.url %> </li>
Try something like this:
$('#your_div_id').append('<%= escape_javascript(raw render :partial => 'your_form_partial') %>')
This will add the contents of your ruby partial to the DOM.

Routing error in Rails 3

I have the following in my view (index.html.erb) code:
<% #projects.each do |project| %>
<%= link_to (#project) do %>
<div id="tombstone">
...Some HTML here...
</div>
<% end %>
<% end %>
The goal is to have each project's synopsis displayed inside the tombstone DIV and have the entire DIV act as the link to the project's details page (show.html.erb).
My Controller has the following:
def show
#project = Project.find(params[:id])
end
and the routes has the following:
resources :projects do
...
resources :updates
end
The #project in the <%= link_to %> points back to the projects (index.html.erb) page, not to the project details page (show.html.erb) that the controller defines. I can only guess that the ID parameter isn't getting passed, but I can't figure out why.
<%= link_to(project) do %> # not #project
Technically you've been sent to index because #project probably new record. #project == Project.new, so link_to(Project.new) with GET request renders path to index action.

Resources