Why is my Flash.now not outputting after a render? - ruby-on-rails

I have a minor issue I can't seem to figure out.
Regular flash works just as intended.
flash[:test] = 'Blarrgh'
redirect_to etcs_url
Will display 'Blarrgh' since I have this code in my application.html.erb
<% if flash[:test] %>
<%= flash[:test] %>
<% elsif flash.now[:test] %>
<%= flash.now[:test] %>
<% end %>
I'm pretty sure the way to display flash.now[:test] messages is just flash[:test], but I added the elsif in the bottom just in case since things weren't working.
For some reason, when I do
flash.now[:test] = 'Blarrgh'
render :edit
Nothing shows up at all. But when I put a 'fail' statement into my view then check out the values, flash[:test]/flash.now[:test] will have the proper values. E.g, ['Etc can't be blank']
I tried checking out common errors: no CSRF token, hidden redirect, flash.now b4 render, using form_with without local:true, but looking at my logs, there's no such issue. I included the CSRF token and my log path is
In logs:
patch /etc/1
(Commit fails, rolls back)
renders application.html.erb which yields etcs/edit.html.erb which renders etcs/_form.html.erb, then renders rest of etcs/edit.html.erb
And I'm putting my flash.now b4 the render. I'm also not using Rails helper functions like form_with.

Never mind, I figured it out. Rails is absolutely insane sometimes, apparently.
If you do a
Flash.now[:errors] = 'This is an error'
render :edit
This won't work. You have to do
Flash.now[:errors] = 'This is an error'
render :edit, status: :whatever_status
This doesn't show up as an error in the browser console, for some reason. It just simply doesn't display your flash.now. Supposedly, it's an issue with Rails 7's turbo being demanding as hell. I hope this saves someone from dealing with an awful lot of pain and misery.
Found the answer from Alex's reply in Flash is not displayed in the same view in Rails

Related

rails doesn't render javascript with Gist Data within partial for ajax request for

I'm learning rails and facing some troubles with understanding following issue.
I have partial _answer.html.slim
Within partial I'm checking if link is gist and render gist
-if link.gist?
= javascript_include_tag("#{link.url}.js")
-else
= link_to link.name, link.url
The new link I'm adding with ajax request by calling create.js.erb
`$('.answer-errors').html('<%= render 'shared/errors', resource: #answer%>');
<% if #answer.persisted?%>
$('.answers').append('<%= escape_javascript(render #answer) %>');
$('#answer_title').val('');
<% end %>`
But by gist doesn't appear at all. It's only appear after refresh DOMe.
So why does it happen? And how to fix it?
So I tried to run ajax call within script but I think smth went wrong and I got 500

In Ruby (2.2) on Rails How Do I Have A Confirmation Box Pop Up Then Redirect To Another Page

In my controller I have an if condition and I want an alert/confirmation box to pop up if it is satisfied, then when the user clicks "ok" to redirect to another page.
I've tried
flash[:alert] = 'Successfully checked in'
redirect_to check_in_path
However it just skips the alert part and goes straight to the redirect without an alert message.
My Ruby version is ruby 2.2.6p396 and rails is 5.0.1
Any help would be appreciated
You need to create a js.erb file. You can then use your existing rails code along with a js alert box. Js.erb files let you combine rails and JavaScript code in the same file. As mentioned flash[:alert] is not an alert box, alert is a css class.
Rails is limited to the respond to HTTP request with HTML. And what you describe sounds more like a JavaScript alert. What you tried, if configured properly*, will simply show the flash alert when the check_in_path page is rendered.
* Get familiar with how the flash works, Rails Guides
You have your controller set up correctly. The only other part I meant by configured correctly is that in your views you should display said flash message:
<% flash.each do |name, msg| -%>
<%= content_tag :div, msg, class: name %>
<% end -%>
It's common to use the name of the flash to style it to make to make it's intent clear; commonly red for failure, green for success.
you can do it as follows
render :update do |page|
page << "alert('Successfully checked in')"
page.redirect_to check_in_path
end
but partial rendering in controller is most commonly used together with Ajax calls. so you may have to make an ajax call to your action from your view page. Hope this will help you

Ruby on rails flash notice error

I have a problem with flash[:notice] = "Message" in Ruby on Rails.
I am trying to create login fault error message. My login fault handling is:
flash[:notice] = "Invalid username/password combination."
redirect_to(:action => 'login')
For the reason I don't know, alert just doesn't show up. I have red tons of possible solutions, but all of them just doesn't work for me. I am using Safari / Google Chrome web browsers.
Your controller code looks fine. I suspect your problem is not that you are calling the flash method incorrectly in your controller, but rather that you did not write the code (correctly) to display the flash in your view.
flash simply holds a message for your views to display. You are setting the message correctly, but you may not be displaying it properly. I can't tell because you aren't posting your view code.
For example, if this action is the result of submitting a user/login.html.erb form, based on your controller code, you would want to have the following code inside that view file:
<% flash.each do |key, value| %>
<div class="alert"><%= value %></div>
<% end %>
This code is a more basic version of what is described in this article.

Using Private-pub with channels that have segment keys and coffeescript variant

I'm trying to replicate a push notification system similar to facebook's using private_pub. Ideally I would want to link this to show notifications using a gem such as gritter (other gem suggestions are welcome)
Whenever a certain action from a controller is called, I want to send a notification to all subscribers that are part of a specific id. As long you are logged in, you are subscribed to the channel, achieved by putting the subscribe_to in the layouts.
in the view:
<%= subscribe_to "/messages/#{#group_id}" %>
in the controller
PrivatePub.publish_to("/messages/#{#group_id}", "alert('test')")
this works just fine, however I would like to have something more sophisticated than an alert as a response (such as a gritter notification), so instead:
PrivatePub.publish_to("/messages/#{#group_id}", data: #some_data)
Following the tutorial, they use coffeescript for this. However, I cannot get the simple alert going (probably due to the id in the channel)
In this question, the OP was able to solve this using a js.erb view. But I can't get it to work.
disclaimer: my js and coffeescript knowledge is almost zero.
Any help is appreciated :)
EDIT
Some more info: I've a method in a controller that's part of a public API, and expects POST request. If everything is ok it sends out a JSON success response. Aside from this, the same method sends a notification to all users of a specific group.
I've actually managed to get this working, putting this in the controller:
callback method:
respond_to do |format|
format.js #-> calls callback.js.erb
#format.json { render json: {"success" => true}.to_json }
end
and putting the gritter stuff in my_api_controller/callback.js.erb:
<% publish_to "/messages/#{#group_id}" do %>
<%= add_gritter(
"Nova " + link_to("reserva", reservation_path(#r)) + " de #{#channel} para " +
link_to(#hostel_name, hostel_path(#hostel_id)),
:title => "Nova reserva!",
:sticky => true,
:image => :notice
) %>
<% end %>
note: since the subscription to the channel is done in every view (through the layout), you can receive a notification on any page/view
My problem at the momento is, as you can guess, the JSON response. Since I cant render two responses, only the js.erb is called, but the JSON response is never sent
Although I've not got much experience with this gem, here's something which may help:
JS
Client-side, your JS is basically running an eventlistener on the private_pub object (defined when you include the private_pub / gritter JS on your page), which you can use to perform other actions (call alerts, append data to page, etc)
It seems your back-end is working, it's just the receipt & processing of the data from the server you're struggling with. To remedy this, you can do 2 things: 1) run a standard JS call from application.js or run a js file from your controller action:
Controller
According to the private_pub documentation, you should do this to create a JS file:
#app/controllers/your_controller.rb
def create
#message = "Hello"
respond_to do |format|
format.html { PrivatePub.publish_to("/messages/#{#group_id}", "alert('test')") }
format.js #-> calls create.js.erb
end
end
#app/views/your_controller/create.js.erb
<% publish_to "/messages/new" do %>
$("#chat").append("<%= j render(#messages) %>");
<% end %>
Browser
#app/assets/javascripts/application.js.coffee
PrivatePub.subscribe("/messages/new", (data, channel) ->
alert data.message.content
I was able to accomplish this by directly adding the gritter script in the publish_to method of Privat pub.
In my controller:
PrivatePub.publish_to
"/some/URI/#{entity.id}"
,"jQuery.gritter.add({
image: '#{ActionController::Base.helpers.asset_path('notice.png')}'
, sticky: true
,title:'#{t('some_title')}'
, text: '#{t('some text'}'
});"
render json: {"error"=>{"code"=>20,"msg"=>e.message},"success" => false}.to_json
Basically, I was able to publish to PrivatePub witouth resorting to the html response, wich enabled me to return a JSON response as intended.
I guess, you can handle your problem with the help of gon gem like below:
In view
<%= subscribe_to "/messages/#{#group_id}" %>
In controller
gon.group_id = #group_id
PrivatePub.publish_to("/messages/#{#group_id}", message: #message)
In messages.coffee
if gon.group_id
PrivatePub.subscribe "/messages/#{gon.group_id}", (data, channel) ->
jQuery.gritter.add
image: '/assets/notice.png'
title: 'Notification!'
text: data.message.content
But, gon.group_id can make trouble sometimes so you need to take care of that.
So, I recommend to use js.erb which is easy and we can access to controller's variable easily in js.erb file.
Hope that answer your problem.

How do I output to website instead of console for debugging in Rails?

Well the title explains pretty much everything.
I want to use something like
p something
And be able to see the output in the website, just for the sake of debugging.
I suspect you're coming from PHP, because this is a very PHP-esque thing to want to do. Standard output isn't sent to the browser in Rails, something PHP developers take for granted.
If you want to see something in browser, you need to render it.
From a view you can use the debug helper to "vardump" a value:
<%= debug something %>
From a controller you can quickly see the value of a variable using render :inline => p(something) or render :inline => something.inspect. Make sure you return afterwards or otherwise prevent yourself from reaching a second render call.
You should get used tailing your log files, and making use of the Rails logger.
I would suggest piggy-backing off of the Rails flash maps. In a controller, use the following:
flash[:log] = "<li>Log: #{log_info}</li>"
Then in your view (possibly in your layout) use:
<% if !flash[:log].blank? && RAILS_ENV != 'production' %>
<ul class="logs">
<%= flash[:log] %>
</ul>
<% end %>
That should put it out on your page!
You can also put the following in ApplicationController
def log(msg)
flash[:log] ||= ""
flash[:log] += "<li>#{Time.new.to_s} - #{msg}</li>"
end
Then simply call from any controller:
log("Hi stackoverflow.")
Or from any view:
#controller.log("Hi there, you!")

Resources