RoR Rails 7 using Turbo to Update a partial on button click - ruby-on-rails

Help! I'm relatively new to Ruby on Rails and now I'm attempting to use Rails 7 with Turbo and Stimulus to update a partial on my web page.
I have buttons on a page within a partial (call it _home.html.erb). When clicked I'd like them to replace _home.html.erb with a different partial.
Let me show you what I've done so far:
view:
index.html.erb
<%= turbo_frame_tag "main-speaker-div" do %>
<%= render partial: 'home' %>
<% end %>```
_home.html.erb
<div class="row">
<div class="col-5">
<%= button_to "Settings", rendersettings_path(), remote: true, class: "reader-general-button"%>
</div>
</div>
controller:
def rendersettings
broadcast_replace_to "main-speaker-div", partial: 'settings'
end
This code is throwing the following error:
POST 500 http://localhost:3000/rendersettings (Internal Server Error)
Response has no matching element
Server console error:
NoMethodError (undefined method `broadcast_replace_to' for #HreaderController:0x0000000002be30):
Thanks in advance for your help!

method broadcast_replace_to is supposed to be called on an object of Model. I guess in your case you must have an Object of header, and this method would be called as #header.broadcast_replace_to

I actually ended up doing the following to with my view to fix this issue:
<%= turbo_stream_from "main-speaker-div" %>
<%= turbo_frame_tag "main-speaker-div" do %>
<turbo-frame id="main-speaker-div">
<%= render partial: 'homefull' %>
</turbo-frame>
<% end %>
It seems like if I am broadcasting I would need to have the turbo_stream_from tag added as a listener. Please point out any issues you see with this! I'm basically doing trial and error since this is so new to RoR

Related

rails turbo frame load new pages instead of showing " Response has no matching" error

i am on rails 7 trying out the turbo frame.
supposedly my code should fire a Response has no matching error because i do not have the similar id in the new page after clicking the new link. however it just loads the new page as usual, contradict with a tutorial. any idea how do i get the error logged instead of loading a new page? thanks.
# app/views/quotes/index.html.erb
<main class="container">
<%= turbo_frame_tag "first_turbo_frame" do %>
<div class="header">
<h1>Quotes</h1>
<%= link_to "New quote", new_quote_path, class: "btn btn--primary" %>
</div>
<% end %>
<%= render #quotes %>
</main>
# app/views/quotes/new.html.erb
<h1>New quote</h1>
<%= render "form", quote: #quote %>

How do you use a turbo frame to replace an object creation form with an object show partial?

I have a model subscription_tier with show and edit actions with corresponding views. I've wrapped each of these with a turbo frame
<%= turbo_frame_tag subscription_tier do %>
When I edit an existing subscription tier and save it, the turbo frame refreshes and shows my saved tier, but I'm unable to replicate this for creating new tiers.
My new tier frame:
<turbo-frame id="new_tier">
<%= link_to "Add Tier", new_create_subscription_tier_path(sub_type: "Free"), class: "btn btn-primary mb-3 fs-6"
%>
</turbo-frame>
and in new.html.erb
<turbo-frame id="new_tier">
<%= render partial: "create/subscription_tiers/edit", locals: {
subscription_tier: #subscription_tier
} %>
</turbo-frame>
Clicking Add Tier button successfully renders the form and I can save the object, but on save the turbo frame is destroyed with the error Response has no matching <turbo-frame id="new_tier"> element
I know this is because my show partial is wrapped with the <%= turbo_frame_tag subscription_tier do %>, but I don't know how to reconcile this.
I believe you need to add a data tag to your new link i.e.
<%= link_to "new subscription", subscription_path, data: { turbo_frame: dom_id(Subscription.new) } %>
On the same page as this link ^^^^ you need to add
<%= turbo_frame_tag Subscription.new %>
I believe this is what your trying to accomplish
There is a fantastic tutorial that goes over all this stuff that is free here
Perhaps the OP figured this out, but for anyone looking for a possible solution, you could always set the turbo frame ID manually, for example:
<!-- new.html.erb, edit.html.erb -->
<%= turbo_frame_tag 'subscription_tier_frame' do %>
<%-- form for subscription tier -->
<% end %>
and
<!-- show.html.erb -->
<%= turbo_frame_tag 'subscription_tier_frame' do %>
<%-- rendered subscription tier -->
<% end %>
That'll keep things in the same turbo frame.

Cannot render partial of another module and pass variables

I am sorry in advance as I know this should be an easy one but I am stuck. I have a show view for "Category" in which I am trying to display related has_many "Subcategories". I am calling the partial by using the following:
<%= render partial: 'subcategories/subcategory', locals: {category: #category }%>
I have an html file in the Subcategories view folder properly named and the partial view loads. I know this because the partial has the code
<%= #category.name %></p>
which shows the correct Category name within the partial. However, when I try to load any of the subcategory data by calling
<% #subcategories.each do |subcategory| %>
<%= subcategory.name%>
<% end %>
I get the error: NoMethodError in Categories#show, undefined method `each' for nil:NilClass
I'm sorry to ask such a basic question but I will be using partials from related modules extensively in this project.
Replace this:
<%= render partial: 'subcategories/subcategory', locals: {category: #category }%>
with this:
<%= render #category.subcategories %>
Then in the partial app/views/subcategories/_subcategory.html.erb do this:
<%= subcategory.name %>

Replace partial with another rails

In my index page I have one partial:
Index-Site:
<div id="chapter_list">
<%= render 'icd1' %>
</div>
This partial _icd1 should have links to another partial _icd2.
Actually _icd1 links to a normal site:
<% #icd1.each do |f| %>
<%= link_to "#{f.von} - #{f.bis} #{f.bezeichnung}", icd_show_path(f), remote: true %>
<% end %>
So my first questionis how can i link to a partial _icd2 with the param "f"?
And next i would like that when a user clicks in the partial _icd1 on the link to _icd2, the partial _icd1 disappears and the partial _icd2 is rendered instead:
So that the index-Site looks like:
<div id="chapter_list">
<%= render 'icd2' %>
</div>
As you can see in my second code snippet my links already respond with ajax. But i have no clue how i can remove the _icd1 partial and display the partial icd2 instead, with js!! So that my icd2.js.erb file actually looks like this:
$('#chapter_list').fadeOut();
Thanks!
$('#chapter_list').html("<%= j render('icd2') %>");

Undefined method 'model_name'

I keep getting a undefined method `model_name' for NilClass:Class.
In the layout file: [application.html.erb]
<section id="featured">
<%= render 'subscribers/new' %>
</section>
In the form partial: [views > subscribers > _new.html.erb]
<%= form_for #subscriber, :url => subscribe_path do |f| %> [THIS LINE PRODUCES THE ERROR]
<div class="field">
<%= f.text_field :email %>
</div>
<div class="actions">
<%= f.submit 'Add me to the list' %>
</div>
<% end %>
In the subscribers controller: [controllers > subscribers_controller.rb]
def new
#subscriber = Subscriber.new
end
I'm a beginner at ROR, and I've looked around StackOverflow, but can't find any answers for my specific case.
What path are you hitting when you are seeing this error?
If you are navigating to any path other than /subscribers/new then #subscriber will be nil and the form will throw the error that you are seeing. You are rendering a form via a partial in your view layout, that layout is rendered (presumably) throughout the app. Thus #subsriber won't always be set.
The problem is, that you are rendering the subscribers/new template directly in the layout, but only initializing a Subscriber in the subscriber controller.
You need to create a subscribers/new.html.erb file (without the leading underscore, so it is not a partial)
Somewhere in your layout file you should have a yield call.
When you access /subscribers/new rails renders the new.html.erb template file, and stuffs it in where yield is called in the layout.
If you really need this form on every page, you will need to initialize a new subscriber on every page. You could do this with a before filter in the application controller. But then you would not need the new action in the subscriber controller.

Resources