Rendering layout with local variable in rails - ruby-on-rails

In my rails controller I have an action that renders a specific layout:
def registrations_for_user
render layout: 'remote_modal', locals: { modal_title: I18n.t('organizations.enrolled_in_learning_item.title') }
end
This layout needs the local modal_title to work, that is why I am passing it up there. Here's the layout :
<div class="relative px-4 w-full max-w-6xl md:h-auto">
<!-- Modal content -->
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<!-- Modal header -->
<div class="w-full">
<div class="flex justify-between items-start p-5 rounded-t">
<div class="w-full-0">
<h3 class="text-lg font-semibold text-gray-900 dark:text-white">
<%= modal_title %>
</h3>
</div>
<i class="close-modal fas fa-times text-lg cursor-pointer"></i>
</div>
</div>
<!-- Modal body -->
<div class="px-6">
<div class="w-full">
<%= yield %>
</div>
</div>
</div>
However I keep getting :
NameError - undefined local variable or method `modal_title' for #<ActionView::Base:0x000000000656f8>:
app/views/layouts/remote_modal.html.erb:9
Is it not possible to pass a local to a layout in rails ? Is there another way to do it ? I've read answers that suggested using a #variable but that does not seem like a clean way to do it.

Related

Using Rails 7 and Taildwincss to put a picture and a card next each other

I'm trying to implement the following design, using Rails 7 with Tailwindcss:
I'm new to Taildwincss and I realize there are many ways to achieve this design. However I cannot fully replicate it. This is the code I'm using in my view:
<div class="grid gap-1 grid-cols-12 grid-rows-1">
<% #user.each do |user| %>
<% if user.photo? %>
<div class="p-5 col-span-2">
<div class="bg-white p-5 rounded-lg shadow-lg">
<%= image_tag "user_photo.png", width: 100 %>
</div>
</div>
<% else %>
<%# ToDo: %>
<%# image_tag user.photo, width: 100 %>
<% end %>
<div class="p-5 col-span-10">
<div class="bg-white p-5 rounded-lg shadow-lg">
<h2 class="text-2xl font-bold mb-2 text-gray-800"><%= user.name %></h2>
<p class="text-gray-700 text-right">Number of posts: <%= user.posts.count %></p>
</div>
</div>
<%end%>
</div>
And this is the result:
What could I change to get a bit closer to the wireframe?
Keep both the div containing both the image and card in flex and add item-center class to it.
Refer to this pseudo code
<div class="flex flex-row item-center">
<div class="bg-white rounded-lg shadow">Image</div>
<div class="bg-white rounded-lg shadow">
card
</div>
</div>
And here is the solution code
<script src="https://cdn.tailwindcss.com"></script>
<div class="flex flex-row items-center">
<div class="p-10">
<div class="rounded-lg bg-gray-200 p-10 shadow-lg">%></div>
</div>
<div class="p-5">
<div class="rounded-lg bg-gray-200 p-5 shadow-lg">
<h2 class="mb-2 text-2xl font-bold text-gray-800">Lily</h2>
<p class="ml-28 text-right text-gray-700">Number of posts: 2</p>
</div>
</div>
</div>

Rails 6 Show or Hide a div if the cookie value matches a token in database

I am building a rails 6 application, and have the requirement that I have to show a banner with a "cookie acceptance".
I have built said banner and when they click the accept button a cookie is created with an "acceptance token", saved to the database and displayed in the cookie.
What I am trying to achieve is to hide that banner if the cookie is present, and the cookie token mates record in the database.
I am stuck on how to call the cookie and match the value against the database. Any assistance here would be great.. cookies are brand new to my world!
my cookie create method: - WORKS
def create
#cookie_acceptance = CookieAcceptance.new(cookie_acceptance_params)
params[:ip_address] = request.remote_ip
return unless #cookie_acceptance.save
cookies[:roadze_cookie_acceptance] = {
value: #cookie_acceptance.accept_token,
expires: 1.year.from_now
}
end
My banner:
<div class="fixed bottom-0 inset-x-0 pb-2 sm:pb-5" id="cookieBanner">
<div class="max-w-screen-xl mx-auto px-2 sm:px-6 lg:px-8">
<div class="p-2 rounded-lg bg-blue-600 shadow-lg sm:p-3">
<div class="flex items-center justify-between flex-wrap">
<div class="w-0 flex-1 flex items-center">
<span class="flex p-2 rounded-lg bg-blue-800">
<div class="flex items-center justify-center h-6 w-6 text-white">
<i class="far fa-question fa-1x"></i>
</div>
</span>
<p class="ml-3 font-medium text-white truncate">
<span class="md:hidden">
This site uses cookies to help your experience.
</span>
<span class="hidden md:inline">
Attention: <span class="logo-font font-bold">roadze<span class="text-xs">.io</span></span> uses cookies to help your overall user experience, and to allow us to offer products specific to your region. <%= link_to "View cookie policy", '#', class: "text-white ml-3 hover:underline" %>
</span>
</p>
</div>
<div class="order-3 mt-2 flex-shrink-0 w-full sm:order-2 sm:mt-0 sm:w-auto">
<div class="rounded-md shadow-sm">
<%= form_for(#cookie_acceptance, remote: true) do |ca| %>
<%= ca.hidden_field :ip_address, value: params[:ip_address] %>
<%= ca.submit 'Accept', class: 'flex items-center justify-center px-4 py-2 border border-transparent text-sm leading-5 font-medium rounded-md text-blue-600 bg-white hover:text-blue-500 focus:outline-none focus:shadow-outline transition ease-in-out duration-150' %>
<% end %>
</div>
</div>
<div class="order-2 flex-shrink-0 sm:order-3 sm:ml-2">
<button type="button" class="-mr-1 flex p-2 rounded-md hover:bg-blue-500 focus:outline-none focus:bg-blue-500 transition ease-in-out duration-150" aria-label="Dismiss">
<svg class="h-6 w-6 text-white" stroke="currentColor" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
</div>
</div>
</div>
</div>
You should stop rendering the partial itself like below(notice condition at the end)
<div>
...
<%= render 'global/marketing/cookie_banner', cookie_acceptance: at_symbol cookie_acceptance if cookie_accepted? %>
...
</div>
and you should have helper method in ApplicationHelper or relevant helper
def cookie_accepted?
CookieAcceptance.exists?(accept_token: cookies[:roadze_cookie_acceptance])
end
if this check is required in controllers as well, you can move above method from helper to ApplicationController and mark this method as helper_method. This way you will be able to use cookie_accepted? across views and controllers.
So this may be a bit "hackie", however I achieved my objective by setting the following in my application_controller
before_action :validate_cookie_presnece
def validate_cookie_presnece
return unless cookies.present?
#cookie = CookieAcceptance.find_by(accept_token: cookies[:roadze_cookie_acceptance]).present?
end
all seems to be working well!

Rails HTML embedding not working correctly

so I'm trying to show some blog-type data on one of my pages. It works fine, but is posting the posts all at the end of the div as well.
Like this:
Image
<div class="style-2 mb-20 shadow bordered light-gray-bg news-margin col-md-5">
<!-- page-title start -->
<!-- ================ -->
<h1 class="page-title">Latest News</h1>
<div class="separator-2"></div>
<!-- page-title end -->
<p class="lead">The latest news will be posted here:</p>
<div class="row grid-space-12">
<%=# news.each do |news| %>
<div class="col-sm-12">
<div class="image-box style-2 mb-20 shadow bordered text-center">
<div class="overlay-container">
<i class="fa fa-newspaper-o fa-5x p-20"></i>
<div class="overlay-to-top">
<p class="small margin-clear"><em> <%= news.topic %> <br> <%= news.created_at.strftime("%A, %b %d") %></em>
</p>
</div>
</div>
<div class="body">
<h3><%= news.header %></h3>
<div class="separator"></div>
<p>
<%=n ews.content %>
</p>
Read More<i class="fa fa-arrow-right pl-10"></i>
</div>
</div>
</div>
<% end %>
</div>
</div>
Figured it out, I had the = in with <%= news.each do |news| %>, which was printing that info out...

Trying to create a specific data-target for bootstrap modal through ruby iteration

I am using bootstrap modal on my rails project. On this page I have to iterate through my slides and for each slide I want to create a modal. I came up with this solution:
<% #slides.each do |slide| %>
<div class="row slidecard text-center">
<div class="col-xs-12 ">
<h2><%= slide.name.upcase %></h2>
<p><em><%= slide.description %></em></p>
<a href="#" data-target=<%=slide.id%> data-toggle="modal">
<%= image_tag slide.picture.url(:medium) %>
</a>
<div class="modal fade" id= <%=slide.id%>>
<div class="modal-dialog mymodal">
<div class="modal-content text-center">
<div class="modal-body">
<%= image_tag slide.picture.url(:original) %>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div
</div>
I give to the link containing the image the data-target attr and gives it the value that has the slide.id so I can give a specific id and data target that links image and modal. But the problem is that for the modal to work I need to add "#"in front of slide.id to have something that looks like data-target="#39"
I tried a couple of things such has :
data-target= "#"<%=slide.id%>
and other stuff but nothing gives me the result I want and make the modal work !
licence
try to this

Multiple ajax forms in same page does not work properly

I have a problem with multiples ajax forms in index view, only first works with remote: true attribute.
This is my index view with a forms
<% #mensagens.each do |mensagem| %>
<%= form_for(mensagem, remote: true,:authenticity_token => true) do |f| %>
<div class="row">
<div class="col-md-9">
<div class="widget">
<!-- BLOCK -->
<div class="row innerAll half border-bottom">
<div class="col-sm-12">
<div class="media-body">
<div class="innerAll half">
<div class='col-md-10'><%= f.number_field :avaliacao %></div>
<div class='col-md-2'><%= mensagem.slug %></div>
</div>
</div>
</div>
</div>
<div class="row innerAll half border-bottom">
<div class="col-sm-12">
<div class="media-body">
<div class="innerAll half">
<%= f.text_area :texto, :class=>"col-md-12 form-control", :placeholder=>"Mensagem" %>
</div>
</div>
</div>
</div>
<div class="row innerAll half border-bottom">
<div class="col-sm-12">
<div class="media-body">
<div class="innerAll half ">
<div class="col-md-2"><%= f.check_box :aprovado %></div>
<div class="col-md-2"><%= f.check_box :status %></div>
<div class="col-md-6 btn"><%= f.text_field :autor,:class=>"form-control", :placeholder=>"Autor" %></div>
<div class="col-md-2"><%= f.submit "Salvar", :class=>"btn btn-success" %></div>
</div>
</div>
</div>
</div>
<div class="row innerAll half border-bottom">
<div class="col-sm-12">
<div class='notyfy_wrapper mensagem_<%= mensagem.id %>'>
<div class="notyfy_message">
<span class="notyfy_text">
<div id="alerta"></div>
</span>
</div>
</div>
</div>
</div>
</div>
<!-- BLOCK -->
</div>
</div>
<% end %>
<% end %>
This is a result: (http://droido.com.br/html.html)
This first form works fine! but second, send a normal request (non-ajax) and redirect to show page!
At droido.com.br/mensagens the second form is nested inside the first. It appears the second This is why it isn't being set up with ajax, as forms are not supposed to be nested, so I expect Rails is not getting to it.
The problem is, based upon your code above, I am not finding any missing close tags. On the page it looks like the <div class='row'> is missing the closing tag. I suggest you knock out a section at a time until you find the problem. Or, delete the entire content and add back until you find it.
Have you used the Chrome dev tools? If not, try it out. Go to the web page, right click, inspect. It will show the tags in a hierarchical manner.

Resources