Correct way to use nested link_to? - ruby-on-rails

<%= link_to controller: :personal_data, class:"px-6 py-4 flex items-center text-sm font-medium" do%>
<span class="flex-shrink-0 w-10 h-10 flex items-center justify-center border-2 border-red-600 rounded-full">
<span class="text-red-600">01</span>
</span>
<span class="ml-4 text-sm font-medium text-red-600">Personal Data</span>
<% end %>
The view seems to make it that the class attribute is a GET function. Here's the generated HTML
<a href="/personal_data?class=px-6+py-4+flex+items-center+text-sm+font-medium">
<span class="flex-shrink-0 w-10 h-10 flex items-center justify-center border-2 border-red-600 rounded-full">
<span class="text-red-600">01</span>
</span>
<span class="ml-4 text-sm font-medium text-red-600">Personal Data</span>
</a>
How should I write it so that the class would be working as it should be?

You can set url using personal_data_path
<%= link_to personal_data_path, class:"px-6 py-4 flex items-center text-sm font-medium" do%>
<span class="flex-shrink-0 w-10 h-10 flex items-center justify-center border-2 border-red-600 rounded-full">
<span class="text-red-600">01</span>
</span>
<span class="ml-4 text-sm font-medium text-red-600">Personal Data</span>
<% end %>

Related

Rails: undefined local variable or method `tenant' for #<ActionView::Base:>

I'm currently trying to render a partial with errors messages if when a form submission fails to create a tenant instance. Im using locals as described in the Rails documentation to pass variables to a partial.
controllers/tenants_controller.rb
def new
#unit = Unit.find(params[:unit_id])
#tenant = Tenant.new
end
def create
#unit = Unit.find(params[:unit_id])
#tenant = #unit.tenants.new(tenant_params)
if #tenant.save
redirect_to #tenant
else
Rails.logger.error('Unable to save Tenant')
render 'new'
end
end
In here im redirecting to the new template if the #tenant fails to be created. This should be adding errors to the #tenant
tenants/new.html.erb
<div class="py-6">
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
<h1 class="text-2xl font-semibold text-gray-900">
Let's add the tenant's information
</h1>
</div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
<!-- Replace with your content -->
<%= form_for [#unit, #tenant], html: { class: "space-y-8 divide-gray-200" } do |f| %>
<%= render 'errors', locals: { tenant: f.object } %>
<div class="space-y-8 divide-y divide-gray-200 sm:space-y-5">
<div class="pt-8 space-y-6 sm:pt-10 sm:space-y-5">
<div class="space-y-6 sm:space-y-5">
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
<%= f.label :first_name, 'First name' %>
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<%= f.text_field :first_name, value: "Albert", class: "block max-w-lg w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 rounded-md" %>
</div>
</div>
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
<%= f.label :last_name, 'Last Name' %>
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<%= f.text_field :last_name, value: "Terry", class: "block max-w-lg w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 rounded-md" %>
</div>
</div>
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
<%= f.label :last_name, 'Last Name' %>
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<%= f.text_field :last_name, value: "Terry", class: "block max-w-lg w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 rounded-md" %>
</div>
</div>
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
<%= f.label :email, 'Email' %>
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<%= f.text_field :email, value: "example#gmail.com", class: "block max-w-lg w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 rounded-md" %>
</div>
</div>
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
<%= f.label :phone_number, 'Phone' %>
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<%= f.text_field :phone_number, value: "(000)000-0000", class: "block max-w-lg w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 rounded-md" %>
</div>
</div>
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
<%= f.label :lease_start_date, 'Lease start date' %>
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<%= f.text_field :lease_start_date, value: "", class: "block max-w-lg w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 rounded-md" %>
</div>
</div>
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2">
<%= f.label :lease_end_date, 'Lease end date' %>
</label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<%= f.text_field :lease_end_date, value: "", class: "block max-w-lg w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 rounded-md" %>
</div>
</div>
<div class="sm:border-t sm:border-gray-200 sm:pt-5">
<div>
<%= f.label :notes, 'Add your notes & documents', class: "block text-sm font-medium text-gray-700" %>
<div class="mt-1">
<%= f.rich_text_area :notes, class: "shadow-sm focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 rounded-md" %>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="pt-5">
<div class="flex justify-end">
<%= link_to 'Cancel', unit_path(#unit), class: "bg-white py-2 px-4 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" %>
<%= f.submit "Save", class: "ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" %>
</div>
</div>
<% end %>
<!-- /End replace -->
</div>
Here im passing tenant variable via the locals however it doesn't seem to be passing the variable to the partial errors in the line <%= render 'errors', locals: { tenant: f.object } %>
When the errors partial is rendered an error is raised.
tenants/_errors.html.erb
<% if tenant.errors.any? %>
<div class="rounded-md bg-red-50 p-4">
<div class="flex">
<div class="flex-shrink-0">
<!-- Heroicon name: mini/x-circle -->
<svg class="h-5 w-5 text-red-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd" />
</svg>
</div>
<div class="ml-3">
<h3 class="text-sm font-medium text-red-800">
There were <%= tenant.errors.count %> errors with your submission
</h3>
<div class="mt-2 text-sm text-red-700">
<ul role="list" class="list-disc space-y-1 pl-5">
<% tenant.errors.full_messages.each do |error_message| %>
<li><%= error_message %></li>
<% end %>
</ul>
</div>
</div>
</div>
</div>
<% end %>
Any idea why
undefined local variable or method `tenant' for #<ActionView::Base
is being raised?
You are calling render incorrectly.
You have two options. You can call it like this:
<%= render partial: 'errors', locals: { tenant: f.object } %>
or like this:
<%= render 'errors', { tenant: f.object } %>

AlpineJS modal closed when clicking upload file input

I created a modal using Alpine JS and TailwindCSS in a Rails app. my problem with that is when I click file upload button the modal closed to open the file browsing popup.
I need the modal to be still open so that I can view the file that the user uploaded.
Is there a way in AlpineJS to keep the modal open? OR do you have any alternative solution?
Code:
<div x-data="{'isModalOpen': false}" >
<div class="p-3 flex items-center gap-3 rounded-md hover:bg-gray-100 transition ease-in-out duration-150">
<%= heroicon(:outline, :user, 'h-5 w-5 text-gray-900') %>
<button x-on:click="isModalOpen = true" class="text-sm font-medium">
<%= t('sidebar.user_profile') %>
</button>
</div>
<div
class="modal"
role="dialog"
tabindex="-1"
x-show="isModalOpen"
x-cloak
x-transition
>
<div class="relative z-10" aria-labelledby="modal-title" role="dialog" aria-modal="true">
<div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity"></div>
<div class="fixed z-10 inset-0 overflow-y-auto">
<div class="flex items-end sm:items-center justify-center min-h-full p-4 text-center sm:p-0">
<div class="relative bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:max-w-lg sm:w-full sm:p-6">
<div class="hidden sm:block absolute top-0 right-0 pt-4 pr-4">
<button type="button" class="bg-white rounded-md text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<span class="sr-only">Close</span>
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="sm:flex sm:items-start">
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">User Profile</h3>
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label for="last-name" class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"> Last name </label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<input type="text" name="last-name" id="last-name" autocomplete="family-name" class="max-w-lg block w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:max-w-xs sm:text-sm border-gray-300 rounded-md">
</div>
</div>
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label for="email" class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"> Email address </label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<input id="email" name="email" type="email" autocomplete="email" class="block max-w-lg w-full shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 rounded-md">
</div>
</div>
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
<label for="cover-photo" class="block text-sm font-medium text-gray-700 sm:mt-px sm:pt-2"> Cover photo </label>
<div class="mt-1 sm:mt-0 sm:col-span-2">
<div class="max-w-lg flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-md">
<div class="space-y-1 text-center">
<svg class="mx-auto h-12 w-12 text-gray-400" stroke="currentColor" fill="none" viewBox="0 0 48 48" aria-hidden="true">
<path d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg>
<div class="flex text-sm text-gray-600">
<label for="file-upload" class="relative cursor-pointer bg-white rounded-md font-medium text-indigo-600 hover:text-indigo-500 focus-within:outline-none focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-indigo-500">
<span>Upload a file</span>
<input id="file-upload" name="file-upload" type="file" class="sr-only">
</label>
<p class="pl-1">or drag and drop</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
<button type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm">Deactivate</button>
<button type="button" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:mt-0 sm:w-auto sm:text-sm">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Unable to find link "New country" (Capybara::ElementNotFound)

Please, help!
I run the test (cucumber) and it gives this error : Unable to find link "New country" (Capybara::ElementNotFound)
<% content_for :page_header do %>
<% render partial: "layouts/app_page_header" , locals: { page_title: "Countries" } %>
<% end %>
<div class="flex flex-col">
<div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
<div class="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th scope="col" class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Country code
</th>
<th scope="col" class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Country name
</th>
<th scope="col" class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Cities count
</th>
<th scope="col" class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Legal forms count
</th>
<th scope="col" class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Taxation forms count
</th>
<th scope="col" class="px-6 py-3 bg-gray-50">
<span class="sr-only">Actions</span>
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200" id="countries">
<%= render #countries %>
</tbody>
</table>
</div>
</div>
</div>
</div> <br>
<%= link_to t('.new_country_button'), new_admin_country_path, id:'new_admin_country_submit', class: 'btn btn-primary' %>
<p>
<%== render partial: "shared/pagy" , locals: {pagy: #pagy} if #pagy.pages> 1 %>
</p>
when I enter "print page.html" it shows that I am on the correct page and I don’t understand why I don’t find the "New country" button I need.
UPD
so I ran the command "puts page.body" in the console and got the html
<!DOCTYPE html>
<html>
<head>
<title>CosmoPort</title>
<script src="/packs-test/js/application-0a4f8f4726a3a8685a4c.js"></script>
</head>
<body>
<div
x-data="{ sidebarOpen: false }"
#keydown.window.escape="sidebarOpen = false"
class="h-screen flex overflow-hidden bg-gray-100">
<!-- Off-canvas menu for mobile, show/hide based on off-canvas menu state. -->
<div
x-show="sidebarOpen"
x-description="Off-canvas menu for mobile, show/hide based on off-canvas menu state."
class="md:hidden">
<div class="fixed inset-0 flex z-40">
<div
#click="sidebarOpen = false"
x-show="sidebarOpen"
x-description="Off-canvas menu overlay, show/hide based on off-canvas menu state."
x-transition:enter="transition-opacity ease-linear duration-300"
x-transition:enter-start="opacity-0"
x-transition:enter-end="opacity-100"
x-transition:leave="transition-opacity ease-linear duration-300"
x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="fixed inset-0" aria-hidden="true">
<div class="absolute inset-0 bg-gray-600 opacity-75"></div>
</div>
<div
x-show="sidebarOpen"
x-description="Off-canvas menu, show/hide based on off-canvas menu state."
x-transition:enter="transition ease-in-out duration-300 transform"
x-transition:enter-start="-translate-x-full"
x-transition:enter-end="translate-x-0"
x-transition:leave="transition ease-in-out duration-300 transform"
x-transition:leave-start="translate-x-0"
x-transition:leave-end="-translate-x-full"
class="relative flex-1 flex flex-col max-w-xs w-full pt-5 pb-4 bg-gray-800">
<div class="absolute top-0 right-0 -mr-12 pt-2">
<button
x-show="sidebarOpen"
#click="sidebarOpen = false"
class="ml-1 flex items-center justify-center h-10 w-10 rounded-full focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white">
<span class="sr-only">Close sidebar</span>
<!-- Heroicon name: x -->
<svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
</svg>
</button>
</div>
<div class="flex-shrink-0 flex items-center px-4">
<img class="h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-logo-indigo-500-mark-white-text.svg" alt="Workflow">
</div>
<div class="mt-5 flex-1 h-0 overflow-y-auto">
<nav class="px-2 space-y-1">
<a class="sidebar-navigation-link" href="/">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
Dashboard
</a>
<a class="sidebar-navigation-link active" aria-current="page" href="/admin">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"
aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/>
</svg>
Admin
</a><br/>
<div class="space-y-1">
<h3 class="px-3 text-xs font-semibold text-gray-500 uppercase tracking-wider" id="admin-headline">
Admin
</h3>
<ul class="space-y-1" role="group" aria-labelledby="admin-headline">
<li>
<a class="sidebar-submenu-link" href="/admin/users">Users</a>
</li>
<li>
<a class="sidebar-submenu-link active" aria-current="page" href="/admin/countries">Countries</a>
</li>
<li>
<a class="sidebar-submenu-link" href="/admin/cities">Cities</a>
</li>
<li>
<a class="sidebar-submenu-link" href="/admin/legal_forms">Legal forms</a>
</li>
<li>
<a class="sidebar-submenu-link" href="/admin/taxation_forms">Taxation forms</a>
</li>
<li>
<a class="sidebar-submenu-link" href="/admin/businesses">Businesses</a>
</li>
<li>
<a class="sidebar-submenu-link" href="/admin/conversations">Conversations</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div class="flex-shrink-0 w-14" aria-hidden="true">
<!-- Dummy element to force sidebar to shrink to fit close icon -->
</div>
</div>
</div>
<!-- Static sidebar for desktop -->
<div class="hidden md:flex md:flex-shrink-0">
<div class="flex flex-col w-64">
<!-- Sidebar component, swap this element with another sidebar if you like -->
<div class="flex flex-col h-0 flex-1">
<div class="flex items-center h-16 flex-shrink-0 px-4 bg-gray-900">
<img class="h-8 w-auto" src="https://tailwindui.com/img/logos/workflow-logo-indigo-500-mark-white-text.svg" alt="Workflow">
</div>
<div class="flex-1 flex flex-col overflow-y-auto">
<nav class="flex-1 px-2 py-4 bg-gray-800 space-y-1">
<a class="sidebar-navigation-link" href="/">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
Dashboard
</a>
<a class="sidebar-navigation-link active" aria-current="page" href="/admin">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"
aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"/>
</svg>
Admin
</a><br/>
<div class="space-y-1">
<h3 class="px-3 text-xs font-semibold text-gray-500 uppercase tracking-wider" id="admin-headline">
Admin
</h3>
<ul class="space-y-1" role="group" aria-labelledby="admin-headline">
<li>
<a class="sidebar-submenu-link" href="/admin/users">Users</a>
</li>
<li>
<a class="sidebar-submenu-link active" aria-current="page" href="/admin/countries">Countries</a>
</li>
<li>
<a class="sidebar-submenu-link" href="/admin/cities">Cities</a>
</li>
<li>
<a class="sidebar-submenu-link" href="/admin/legal_forms">Legal forms</a>
</li>
<li>
<a class="sidebar-submenu-link" href="/admin/taxation_forms">Taxation forms</a>
</li>
<li>
<a class="sidebar-submenu-link" href="/admin/businesses">Businesses</a>
</li>
<li>
<a class="sidebar-submenu-link" href="/admin/conversations">Conversations</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
</div>
</div>
<div class="flex flex-col w-0 flex-1 overflow-hidden">
<div class="relative z-10 flex-shrink-0 flex h-16 bg-white shadow">
<button
#click.stop="sidebarOpen = true"
class="px-4 border-r border-gray-200 text-gray-500 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-indigo-500 md:hidden">
<span class="sr-only">Open sidebar</span>
<!-- Heroicon name: menu-alt-2 -->
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h7"/>
</svg>
</button>
<div class="flex-1 px-4 flex justify-end">
<div class="ml-4 flex items-center md:ml-6">
<button class="bg-white p-1 rounded-full text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
<span class="sr-only">View notifications</span>
<!-- Heroicon name: bell -->
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/>
</svg>
</button>
<!-- Profile dropdown -->
<div #click.away="open = false" x-data="{ open: false }" class="ml-3 relative">
<div>
<button
#click="open = !open"
x-bind:aria-expanded="open"
class="max-w-xs bg-white flex items-center text-sm rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" id="user-menu" aria-haspopup="true">
<span class="sr-only">Open user menu</span>
<svg class="h-8 w-8 text-gray-600 rounded-full" fill="currentColor" viewBox="0 0 24 24">
<path d="M24 20.993V24H0v-2.996A14.977 14.977 0 0112.004 15c4.904 0 9.26 2.354 11.996 5.993zM16.002 8.999a4 4 0 11-8 0 4 4 0 018 0z"></path>
</svg>
</button>
</div>
<!--
Profile dropdown panel, show/hide based on dropdown state.
Entering: "transition ease-out duration-100"
From: "transform opacity-0 scale-95"
To: "transform opacity-100 scale-100"
Leaving: "transition ease-in duration-75"
From: "transform opacity-100 scale-100"
To: "transform opacity-0 scale-95"
-->
<div
x-show="open"
x-description="Profile dropdown panel, show/hide based on dropdown state."
x-transition:enter="transition ease-out duration-100"
x-transition:enter-start="transform opacity-0 scale-95"
x-transition:enter-end="transform opacity-100 scale-100"
x-transition:leave="transition ease-in duration-75"
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95"
class="origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5" role="menu" aria-orientation="vertical" aria-labelledby="user-menu">
<a role="menuitem" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" href="/users/edit">Account</a>
<a role="menuitem" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" href="/profiles/edit">Edit profile</a>
<a role="menuitem" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" rel="nofollow" data-method="delete" href="/users/sign_out">Logout</a>
</div>
</div>
</div>
</div>
</div>
<main
x-data=""
x-init="$el.focus()"
class="flex-1 relative overflow-y-auto focus:outline-none" tabindex="0">
<div class="py-6">
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
<h1 class="text-2xl font-bold text-gray-900">
Countries
</h1>
</div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
<div class="flex flex-col">
<div class="-my-2 overflow-x-auto sm:-mx-6 lg:-mx-8">
<div class="py-2 align-middle inline-block min-w-full sm:px-6 lg:px-8">
<div class="shadow overflow-hidden border-b border-gray-200 sm:rounded-lg">
<table class="min-w-full divide-y divide-gray-200">
<thead>
<tr>
<th scope="col" class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Country code
</th>
<th scope="col" class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Country name
</th>
<th scope="col" class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Cities count
</th>
<th scope="col" class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Legal forms count
</th>
<th scope="col" class="px-6 py-3 bg-gray-50 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Taxation forms count
</th>
<th scope="col" class="px-6 py-3 bg-gray-50">
<span class="sr-only">Actions</span>
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200" id="countries">
<tr>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">RU</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">Russian Federation</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">0</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">0</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">0</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<a class="text-indigo-600 hover:text-indigo-900" href="/admin/countries/eb1c9426-8d31-443d-8131-12d5026ec220">Show</a> |
<a class="text-indigo-600 hover:text-indigo-900" href="/admin/countries/eb1c9426-8d31-443d-8131-12d5026ec220/edit">Edit</a> |
<a data-confirm="Are you sure?" class="text-red-600 hover:text-red-900" rel="nofollow" data-method="delete" href="/admin/countries/eb1c9426-8d31-443d-8131-12d5026ec220">Delete</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div> <br>
<a id="new_admin_country_submit" class="btn btn-primary" href="/admin/countries/new">New country</a>
<p>
</p>
</div>
</div>
</main>
</div>
</div>
<footer class="footer">
<div class="container mx-auto mt-5">
© <span id="current_year"></span> CosmoZoo Inc, All rights reserved.
</div>
</footer>
</body>
</html>
test code (
the required line starts with #New country):
password = (0...20).map { ("a".."z").to_a[rand(26)] }.join
# See countries
Given("I am an admin") do
admin_user = FactoryBot.create(:user, name: "Tim Cook", email: "tester#example.com", password: password, confirmed_at: Time.zone.today)
admin_user.add_role :admin
expect(admin_user.has_role?(:admin)).to be_truthy
expect(admin_user).not_to be_nil
end
When("I am log in as an admin") do
visit user_session_path
fill_in "user_email", with: "tester#example.com"
fill_in "user_password", with: password
click_button "Log in"
end
Then("I should be logged in as an admin") do
expect(page).to have_content("Signed in successfully.")
end
When("I create countries") do
FactoryBot.create(:country,
country_code: "RU")
end
Then("I should see countries") do
visit admin_dashboard_path
click_link("Countries", match: :first)
expect(page).to have_content("RU")
puts page.body
end
# New country
When "I submit a new country" do
click_link "New country"
end
Then("I should see the new country") do
pending # Write code here that turns the phrase above into concrete actions
end
From the HTML the element should match the :link selector. That means there's really only a couple of possible reasons.
The link isn't actually visible on the page - add page.save_and_open_screenshot before the click_link to see what the page actually looks like. Is it possible you're not running the browser wide enough, and it's collapsing to a mobile layout or something?
You have CSS being applied to the link which is changing the case of the text - screenshot would show that too
One other thing to try would be click_link('new_admin_country_submit') and see if that actually finds and clicks the link (which would indicate an issue with text case, etc)

Img Kit to create multiple image sizes in rails

Hi I have a small app that shares a png of an image using img kit. These images are for social, so i would like to create multiple image versions for example a 1080 X 1080 version for instagram & a 1240 X 644 for LinkedIn.
The question I am asking is how do i create multiple images for the same view with imgkit
currently the images are created in the controller
def show
respond_to do |format|
format .html
format.png do
kit = IMGKit.new render_to_string, width: 1080, height: 1080
send_data kit.to_png, type: "image/png", disposition: "inline"
end
end
end
and accessed in the view via a share bar
<div class="row d-flex justify-content-center mb-1 mr-lg-5 ml-lg-5 pr-lg-5 pl-lg-5">
<div class="col d-flex justify-content-center align-items-center pt-3 border-dark border-top border-left border-bottom">
<p class="text-justify text-center">SHARE:</p>
</div>
<div class="col facebookshare d-flex justify-content-center align-items-center p-0 m-0 border-dark border-top border-bottom">
<%= link_to "https://www.pinterest.com/pin/create/button/" do %>
<i class="fab fa-facebook-f fa-2x d-none d-sm-block"></i>
<i class="fab fa-facebook-f d-sm-none d-md-none d-lg-none d-xl-none"></i>
<% end %>
</div>
<div class="col instashare d-flex justify-content-center align-items-center p-0 m-0 border-dark border-top border-bottom">
<%= link_to "https://www.pinterest.com/pin/create/button/" do %>
<i class="fab fa-instagram fa-2x d-none d-sm-block"></i>
<i class="fab fa-instagram d-sm-none d-md-none d-lg-none d-xl-none"></i>
<% end %>
</div>
<div class="col twittershare d-flex justify-content-center align-items-center p-0 m-0 border-dark border-top border-bottom">
<%= link_to "https://twitter.com/share?ref_src=twsrc%5Etfw" do %>
<i class="fab fa-twitter fa-2x d-none d-sm-block"></i>
<i class="fab fa-twitter d-sm-none d-md-none d-lg-none d-xl-none"></i>
<% end %>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
<div class="col pinteresrshare d-flex justify-content-center align-items-center p-0 m-0 border-dark border-top border-bottom">
<%= link_to("https://www.pinterest.com/pin/create/button/") do %>
<i class="fab fa-pinterest-p fa-2x d-none d-sm-block"></i>
<i class="fab fa-pinterest d-sm-none d-md-none d-lg-none d-xl-none"></i>
<% end %>
<script async defer src="//assets.pinterest.com/js/pinit.js"></script>
</div>
<div class="col tumblrshare d-flex justify-content-center align-items-center p-0 m-0 border-dark border-top border-bottom">
<%= link_to("http://tumblr.com/widgets/share/tool?canonicalUrl=\#{quote_url(#quote)}", data: {
content: quote_url(#quote, format: 'png'),
caption: #quote.quote,
url: quote_url(#quote) })do %>
<i class="fab fa-tumblr fa-2x d-none d-sm-block"></i>
<i class="fab fa-tumblr d-sm-none d-md-none d-lg-none d-xl-none"></i>
<% end %>
<script id="tumblr-js" async src="https://assets.tumblr.com/share-button.js"></script>
</div>
<div class="col buffershare d-flex justify-content-center align-items-center p-0 m-0 border-dark border-top border-bottom">
<%= link_to("http://bufferapp.com/add", data: {
picture: quote_path(#quote, format: 'png'),
text: "this is the tweet text",
url: quote_path(#quote),
via: "#motiv8kit"}) do %>
<i class="fab fa-buffer fa-2x d-none d-sm-block"></i>
<i class="fab fa-buffer d-sm-none d-md-none d-lg-none d-xl-none"></i>
<% end %>
<script type="text/javascript" src="https://static.buffer.com/js/button.js"></script>
</div>
<div class="col dload d-flex justify-content-center align-items-center p-0 m-0 border-dark border-top border-bottom border-right">
<%= link_to quote_path(#quote, format: "png"), download: "" do %>
<i class="fas fa-download fa-2x d-none d-sm-block"></i>
<i class="fas fa-download d-sm-none d-md-none d-lg-none d-xl-none"></i>
<% end %>
</div>
</div>
quote_path is a named route for show, right? If so, then add the size as a param:
class MyClass
SIZES = {'linkedin' => [1240, 644], 'instagram' => [1080, 1080]}
def show
respond_to do |format|
format .html
format.png do
w, h = SIZES[params[:s]] # Remember to check presence of :s
# and set default values
kit = IMGKit.new render_to_string, width: w, height: h
send_data kit.to_png, type: "image/png", disposition: "inline"
end
end
end
end
In your view (adapt link in any case):
<%= link_to quote_path(#quote, format: "png", s: 'linkeding') do %>
<% end %>
<%= link_to quote_path(#quote, format: "png", s: 'instagram') do %>
<% end %>

To iterate by block in rails

I used Ruby on Rails and I have created more of 40 hiraganas flashcards. In my index view, I do an iteration like this.
Some of Hiraganas cards have different I want to create different columns which host different color cards.
I want to iterate on letter A = green, E = red, I = Pink, etc
enter image description here
I only do that
<% #hiraganas.each do |hiragana| %>
<li>
<%= render 'allhiraganas', hiragana: hiragana %>
</li>
<% end %>
Do you know how to select only few elements to iterate. I see some tutos but I try .select
here is the render flashcards code
<div class="row">
<ul class="list-inline text-center card-frame">
<li>
<div class="card">
<div class="front">
<% if current_user.try(:admin?) %>
<%= link_to hiragana_path(hiragana), class:'trash-hiragana', data: { confirm: 'Are you sure?' }, method: :delete do %>
<%= image_tag("delete-btn.png") %>
<% end %>
<% end %>
<!-- PARAMETRER LE RESPONSIVE BOOTSTRAP -->
<!-- <div class="col-sm- col-xs-4 col-md-3"> -->
<span class="card-question popover-word" data-content="<h4 class='text-center letter-uppercase'><%= hiragana.bigletter.upcase %></h4><p class='text-center'><b><%= hiragana.midletter %></b> comme dans <b><%= hiragana.transcription %></b></p>">
<i class="fa fa-eye fa-lg"></i>
</span>
<!-- son de l'hiragana -->
<span class="audioclick popover-word" data-content="<p class='text-center'><b>le son arrive prochainement !</b></p>">
<i class="fa fa-volume-up fa-lg"></i>
</span>
<!-- image mnémotechnique -->
<span class="idea popover-word" data-content="<p class='text-center'><b>l'image est bientôt prête !</b><%= hiragana.upload %></p>">
<i class="fa fa-lightbulb-o fa-lg"></i>
</span>
<!-- <div class="prononciation">
<i class="fa fa-comment"></i>
</div> -->
<div class="card-hiragana hiragana-<%=hiragana.bigletter.downcase.last%>">
<h1><b><%= hiragana.ideo1 %></b></h1>
</div>
<div class="card-katakana">
<p><%= hiragana.ideo2 %></p>
</div>
<div id="favorite_<%=hiragana.id%>">
<%= render 'favs/favorites', hiragana: hiragana %>
</div>
</div>
<div class="back">
<div class="col-sm-3 col-xs-4 col-md-3 containerbackcards-<%=hiragana.bigletter.downcase.last%>">
<div class="backcard-hiragana">
<h1><b><%= hiragana.ideo1 %></b></h1>
</div>
<div class="card-bigletter">
<h4><%= hiragana.bigletter.upcase %></h4>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
Thank you for your answer
which ones do you want? what's the logic for which you'd like to choose? If you simply wanted the first 3 you could say
#hiriganas = Hirigana.first(3)
if you have a condition you'd like to choose them by select is a good choice.
#hiriganas = #hiriganas.select{ |hir| # criteria for selection }
It depends: If you have the color saved in the hiragana model, then you just need to:
greenhiriganas = Hirigana.where(color: "green")
If you just know in your head, which letters have which colors, then for each section you need to write an array containing all the names
#if for example A, Ka and Shi are green
green = [:a, :ka, :shi]
#then select via include?-method
greenhiriganas = Hirigana.select{ |hiri| green.include?(hiri.name) }

Resources