Using 'content_for' inside a view - ruby-on-rails

I used content_for inside a view. This is my code:
<div class="row">
<div class="col-lg-12">
<div class="panel panel-default">
<%= content_for :youtube_explain %>
</div>
</div>
</div>
<% content_for :youtube_explain do %>
<div>
物件 ⇒ <%= link_to "ント(編)", "https://youtu.be/ZYhR" %>
</div>
<% end %>
It does not seem to display the content in block youtube_explain.

You must define your block of markup before you call it, like:
<%= content_for? :youtube_explain %>
<% content_for :youtube_explain do %>
<div>物件 ⇒ <%= link_to "ント(編)", "https://youtu.be/ZYhR" %></div>
<% end %>
<!-- false -->
Otherwise:
<% content_for :youtube_explain do %>
<div>物件 ⇒ <%= link_to "ント(編)", "https://youtu.be/ZYhR" %></div>
<% end %>
<%= content_for? :youtube_explain %>
<!-- true -->

Related

'nil' is not an ActiveModel-compatible object. It must implement :to_partial_path in rails 7

implementing a <%= render #booking_types %> partial in my home#dashboard view, Why is rails not looking into app/views/booking_types folder for a partial named _booking_type.html.erb and renders it as a looped instance?
app/views/home/dashboard.html.erb
<div class="flex items-center justify-between pb-6 border-b">
<h1 class="font-extrabold text-3xl">Dashboard</h1>
<%= link_to "Create booking type", new_booking_type_path, class: button_class(theme: "primary") %>
</div>
<div class="py-10 grid grid-cols-3 gap-6">
<%= render #booking_types %>
</div>
</div>
the partial
app/views/booking_types/_booking_type.html.erb
<div id="<%= dom_id booking_type %>">
<%= link_to edit_booking_type_path(booking_type), class: "p-6 border shadow-xl rounded-xl block hover:shadow-lg transition ease-in duration-300 relative overflow-hidden" do %>
<div class="h-1 w-full absolute top-0 left-0 right-0" style="background-color: <%= booking_type.color %>">
</div>
<h3 class="font-medium text-2xl"><%= booking_type.name %></h3>
<p class="text-gray-500">View booking page</p>
<p><%= duration(booking_type) %></p>
<% if booking_type.payment_required? %>
<div class="mt-3 pt-3 border-t">
<p>
<strong>Payment required</strong>
</p>
<p>
<strong>Price:</strong>
<%= number_to_currency(booking_type.price) %>
</p>
</div>
<% end %>
<% end %>
</div>
Error Output by better-errors gem after changing rendering partial from <%= render #booking_types %> to this way
<%= render "booking_types/booking_type" %>

Render only when i set it to render

so my question is how can i enable this piece of code only when i want? I have multiple pages and some pages i need to remove that piece of code.
This is my current partial _navbar.html.erb and div.spotlight is the piece of code i need to disable in some pages
<div class="container">
<nav class="logonav">
<div class="row">
<div class="col50"><span class="logo"></span>
<h2>Musicus</h2>
<p>De ti para o mundo</p>
</div>
<% if user_signed_in? %>
<div class="col50">
<%= link_to 'Logout', destroy_user_session_path, class: 'ui-btn btn-normal', method: :delete %>
</div>
<% else %>
<div class="col50">
<%= link_to new_user_registration_path, class: 'ui-btn btn-accent' do %>
<span class="icon-add-user"></span> Criar Conta
<% end %>
<%= link_to new_user_session_path, class: 'ui-btn btn-normal' do %>
<span class="icon-login"></span> Login
<% end %>
</div>
<% end %>
</div>
</nav>
<div class="spotlight">
<%= yield :other_message %>
<%= render 'search' %>
<%= yield :primary_message %>
</div>
<%= yield :other_nav %>
</div>
You can use a simple if statement:
<% if show_spotlight %>
<div class="spotlight">
<%= yield :other_message %>
<%= render 'search' %>
<%= yield :primary_message %>
</div>
<% end %>

Rails 4 - Multiple yield blocks on a partial

Is it possible to have a partial using more than one yield block? I wanted to use it to implement bootstrap modal boxes on my project, kinda like this:
<div class="modal fade" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<%= yield :header %>
</div>
<div class="modal-body">
<%= yield :body %>
</div>
<div class="modal-footer">
<%= yield :footer %>
</div>
</div>
</div>
</div>
And this is more or less how I was thinking of using it
<%= render partial: "shared/modal" do %>
<% content_for :header do %>
...
<% end %> %>
<% content_for :body do %>
...
<% end %> %>
<% content_for :footer do %>
...
<% end %> %>
<% end %>
Is there a way to do this? Is this maybe a bad approach for some reason?
Through much trial and error, I think I solved this in Rails 5 but needed to insert a blank yield in my partial in order to get it to work:
_partial.html.erb
<div class="partial">
<%= yield %> <!--Does not do anything-->
<div class="header">
<%= yield :header %>
</div>
<div class="text">
<%= yield :text %>
</div>
</div>
Implemented as:
full_layout.html.erb
<%= render "partial" do %>
<% content_for :header do %>
<h1>Header content</h1>
<% end %>
<% content_for :text do %>
<p>Text content</p>
<% end %>
<% end %>
I think you have an issue with your render partial. Notice you have all of your content_for blocks within the render partial block.
<%= content_for :thing do %>
Some content
<% end %>
<%= render partial: "blah" %>
It's no problem to use multiple yield blocks in your partial. Only thing is to make sure that many is actually needed. For an example content_for sections are basically placeholders for content that could vary based on the logic of the application. So, it's totally fine to use multiple yields in one page.
You can also just run put an yield there withouth the output. This way you can also use the default block.
<div>
<% yield %>
<div class="mt-3">
<div class="text-2xl tracking-wide font-bold text-gray-900">
heading
<%= yield :heading %>
</div>
</div>
<div class="relative bg-white rounded-xl shadow-xl mb-8 min-h-28">
<%= yield %>
</div>
...

Rails loop not generationg grids

I have a loop that iterates through a list of stories but it's generating one row per story and not 3 columns. What am I missing?
<div class="row">
<div class="col-md-4">
<% #stories.each do |story| %>
<h2><%= story.name.titleize %></h2>
<%= image_tag story.pictures.first.image(:medium).to_s, class: "img-responsive" %>
<%= link_to "View Story", story_path(story) %>
<% end %>
</div>
</div>
Thanks.
I think you're placing the each loop in the wrong place. Try something like:
<div class="row">
<% #stories.each do |story| %>
<div class="col-md-4">
<%= content_tag :h2, story.name.titleize %>
<%= image_tag story.pictures.first.image(:medium).to_s, class: "img-responsive" %>
<%= link_to "View Story", story_path(story) %>
</div>
<% end %>
</div>
Take a look to each_slice
#stories = [story1, story2, story3, story4, story5, story6, story7, story8]
#stories.each_slice(3).to_a
#=> [[story1, story2, story3], [story4, story5, story6], [story7, story8]]
I think you can try this:
<% #stories.each_slice(3).to_a.each do |row_stories| %>
<div class="row">
<% row_stories.each do |story| %>
<div class="col-md-4">
<%= content_tag :h2, story.name.titleize %>
<%= image_tag story.pictures.first.image(:medium).to_s, class: "img-responsive" %>
<%= link_to "View Story", story_path(story) %>
</div>
<% end %>
</div>
<% end %>

Dynamically generate all products on a responsive view using Bootstrap's Grid system

I want to generate all my products and their information on a page using bootstrap's grid system. I tried to generate three products in a row at first and it worked using the following code:
<div class="container">
<h1 align="center">Listing products</h1>
<% #products.each do |product| %>
<% if #a%3 == 0 %>
<div class="row">
<% end %>
<div class="col-lg-4">
<%= image_tag(product.image_url, class: 'list_image', size: '260x320') %>
<%= product.title %> <br/>
<%= product.price %> <br/>
<%= link_to 'Show', product %><br/>
</div>
<% #a = #a+1 %>
<% if #a%3 == 0 %>
</div><hr/>
<% end %>
<% end %>
</div>
(#a is what I declared in the controller which is initially set to 0)
The code will not work anymore if I want to only display two or less products in a row using the grid system when the screen gets smaller.
Are there any better ideas to achieve this?
Seems like you are generating incorrect HTML markup. Try to use each_slice:
<div class="container">
<h1 align="center">Listing products</h1>
<% #products.each_slice(3) do |products| %>
<div class="row">
<% products.each do |product| %>
<div class="col-lg-4">
<%= image_tag(product.image_url, class: 'list_image', size: '260x320') %>
<%= product.title %> <br/>
<%= product.price %> <br/>
<%= link_to 'Show', product %><br/>
</div>
<% end %>
</div>
<hr/>
<% end %>
</div>

Resources