a way to dismiss the notice flash message in rails 3.2 - ruby-on-rails

is there a way to dismiss the standard rails 3.2 forum notice when created a record or logged in with devise? like in twitter-bootstrap there's a cross you can click to dismiss the notice message.
I hope there is a similar way in standard forms.

You asked if there was a simpler way. There is no built in way to do this.... You will need to do something like this:
<% if flash[:notice] %>
<p class="notice"><%= flash[:notice] %></p>
<% end %>
<% if flash[:error] %>
<p class="error"><%= flash[:error] %></p>
<% end %>
In your app/assets/javascripts/flash.js.coffee
$ ->
$(".notice, .error").on("click", (event)->
$(event.target).hide("slow")
)
This will make it where if you click on the .notice or .error, it will hide the slowly (fade out). To this you can include a X icon to close it.

As I understand you not want notice on any particular action so delete <%= notice%> from application.rb file from your layout folder in view.
I hope i understood your question correctly.

Related

How much should I avoid computations in my views?

I am building an application where n users can talk to each other (like a messaging application) in public. Because you might want to have a different bio for each talk you do (for example a discussion about me regarding Ruby on Rails would need a different bio than one about Psychology) I have a Spkr model which has a User and a Tlk. The below code successfully means that on the users profile page, for each instance of them being a Spkr, the Tlk, and it's participants is visible with each Spkr's image (so if a Tlk has three participants, then all three images will be visible).
The setup is such where the default image is the User's image, but the Spkr can also customise their image by uploading one as a Spkr. I am worried that I am loading the front end with too much computation. Right now everything works... so is it ok? Or should I be limiting the computation happening when building views?
Thank you
<% #user.spkrs.each do |spkr| %>
<%= link_to show_tlk_path(spkr.tlk) do %>
<h4><%= spkr.tlk.title %></h4>
<% spkr.tlk.spkrs.each do |speaker| %>
<div class="tlk-tlking-image spkr-image image-spkr-<%= spkr.id %>"
<% if speaker.image.present? %>
style="background-image: url(<%= rails_blob_url(speaker.image) %>)"
<% elsif speaker.user.image.present? %>
style="background-image: url(<%= rails_blob_url(speaker.user.image) %>)"
<% end %>
>
</div>
<p><%= speaker.name %></p>
<% end %>
<% end %>
<% end %>
It tends to be considered good practice to keep the view as free of 'back end' calculations as possible. These files are often worked on by front end developers who may not even know how to code ruby, so the less of it that is in the view the better. It's also just not where it belongs in rail's Model Controller View framework.
First of all the code you've put can be simplified to:
<% #user.spkrs.each do |spkr| %>
<%= link_to show_tlk_path(spkr.tlk) do %>
<h4><%= spkr.tlk.title %></h4>
<% spkr.tlk.spkrs.each do |speaker| %>
<div class="tlk-tlking-image spkr-image image-spkr-<%= spkr.id %>"
style="background-image: url(<%= rails_blob_url((speaker.image || speaker.user.image) %>)"
>
</div>
<p><%= speaker.name %></p>
<% end %>
<% end %>
<% end %>
But as you say, if you want to handle this in a more appropriate place, I'd add a method to the Speaker class:
# app/models/speaker.rb
class Speaker << ApplicationBase
def image_for_view
image || user.image
end
end
This will let you call speaker.image_for_view which I think reads nicely in the view file itself.
Along with the great answer let me just add something that might help you to make views more clear. Might not be relevant to your question directly but might help you to get some idea how you can make views beautiful.
The first thing to make views look good are helpers. Though rails provide helpers for every controller, helpers are global meaning it can be used anywhere in any views. So, global formatings should be done with helpers. Like if you want a date formatter that needs to be used in a lot of view files, you can create a helper called date_helper.rb in app/helpers and put you desired date formatting -
module DateHelper
def formatted_date(date)
date.strftime([%m/%d/%Y')
end
end
Next is what rails people like to call a Presenter pattern. This is helpful when you don't want some logic to be shared across all views. Some logic that doesn't feel like belongs in controller or model are put there to make views readable. Suppose you have a view like below which is a bit messy -
<p>
Post title: <%= post.title.gsub("forbidden word", "") %>
<%= link_to "Read post", post, class: "w-75 p-3 text-#{post.draft? ? "orange" : "green"} border-#{post.draft? ? "orange" : "green"}" %>
</p>
To make this more beautiful you can create a presenter class named post_presenter.rb which should reside in app/presenters and write some code like -
class PostPresenter
def initialize(post)
#post = post
end
def title_without_forbidden_words
#post.title.gsub("forbidden word", "")
end
def css_color
#post.draft? ? "orange" : "green"
end
end
and in the view -
<% presenter = PostPresenter.new(post) %>
<p>
Post title: <%= presenter.title_without_forbidden_words %>
<%= link_to "Read post", post, class: "w-75 p-3 text-#{presenter.css_color} border-#{presenter.css_color}" %>
</p>
Such way a view might be more clear and also it can be lifesaver for frontend developers. This are the best two methods I found till now that makes a rails view beautiful which I always try to use.
Examples are taken from rubyguides website. Thanks to them,

Rails: show.modal on a index.each form

I have and index page showing a list of users. What I want is for when I click on a link_to show a certain user in that #users.each form, that shows up the modal (pop ups fine) but gives the data of that user in it as well.
users/index.html.erb
<div class="container">
<% #users.each do |user| %>
<%= link_to user.name, user, { remote: true, "data-target": "#modal-full" } %>
<% end %>
</div>
<%= render 'layouts/modalfull' %>
layouts/_modalfull.html.erb
<div id="modal-full">
<h1 class="name"></h1>
</div>
UsersController
def show
#user = User.find(params[:id])
redirect_to do |format|
format.js // because that would be where the js code would be to push the data to the modal, right?
end
end
Now how it should go in the in the show.js.erb, I have no idea, I'm really not familiar with those stuffs, still new with Rails.
So right now, what I did, will pop-up the modal but wouldn't send the data from the user I clicked on. And I believe that's on the JavaScript side > show.js.erb.
Continued trying different things and came up with this, which made it work.
Which is partially an answer, you'll know why bellow.
users/show.js.erb
$("#modal-full .name").html("<%= #user.name %>");
But if there is any cleaner way to do this, please share.
Because right now, the thing works, it replaces the name but, we see the change being made. So if I clicked on a John, modal would pop up with "John" written on it. Then I close it and click on "Jennifer", modal will pop up with "John" and takes a second to change it to "Jennifer".

view reviews of a book using conditional logic to determine which reviews to display

I am making a book review/online book group app.
On the individual book show page, I would like to have the user decide whether or not they would like to see reviews, reviews with spoilers or all of it. Therefore when the page loads they should see only the main info about the book, and three buttons: See Reviews, See Spoilers, See All.
Now this seems like it should be a totally easy task. If I were using JS and jQuery, I would just hide all the elements and have the buttons trigger jQuery shows if they match the objects spoiler code, however this does not work in Rails.
I have tried doing js in the view, I have tried running the logic through their own routes, I've tried functions in the controller and helper and nothing works!! Auuugghh! I've been working on this for almost 2 days and want to smash my computer in. Granted, this is my first project back on Rails after 6 months off, I've been working mostly in Node, and my Rails is rusty. Here's the code that may be pertinent, but it's Rails so it's all over the place so it might just be easier to look at the github repo, which is here. https://github.com/nwimmer123/readit_rails
I've been cruising StackOverflow and reading APIDock, but haven't been able to figure this out. Any help would be greatly appreciated.
show.html.erb
<div class="container">
<%= button_to "Show Reviews", class: "btn btn-primary col-xs-2" %>
<%= button_to "Show Spoilers", class: "btn btn-primary col-xs-2" %>
<%= link_to "Show It All", controller: "books", method: "find_reviews", class: "btn btn-primary col-xs-2"%>
</div>
<% if #show_the_reviews == true %>
<div class="container">
<% #reviews.each do |review| %>
<% if review.book_id.to_s == params[:id].to_s %>
<div class="review">
<div>
<strong><%= review.user.name %></strong>
<% if review.spoiler == "1" %>
<span class="center-text">SPOILER</span>
<% end %>
</div>
<p><%= review.body %></p>
<button class="pull-right">Respond</button>
</div>
<% end %>
<% end %>
</div>
<% end %>
</div>
books controller
def show
#user = current_user
#reviews = Review.all
end
private
def book_params
params.require(:book).permit(:title, :author, :genre, :image, :publication_date, :publisher, :synopsis)
end
def current_book
#book = Book.find_by_id(params[:id])
end
def find_reviews
puts "LOOK HERE!!!!!!"
#reviews.each do |review|
if review.book_id.to_s == params[:id].to_s
puts review.spoiler
end
end
#show_the_reviews = true
redirect_to book_path(#book.id)
end
end
When I click Show It All, it redirects to home page?!
Note, I realize this question is poorly written and vague, but I'm super annoyed and can't figure out how to write it better. I think I'm looking for basic strategies here.
You can do it easily with jQuery, just give the reviews an appropriate class..
<% review_class = review.spoiler == true ? ' spoiler' : ' spoiler-free' %>
<div class="review <%= review_class%>">
Then put some <script> at the top of the view that will toggle show/hide for $('.spoiler') and $('.spoiler-free') and have your buttons onclick call the js functions.
You can do it in pure rails by making a field-less form with submit buttons, and in the called action test params[:commit] which will have the text of the button that was clicked, and then use that in conditional logic to filter out whether you retrieve spoiler reviews, non-spoiler reviews, or both. But the jQuery is way more responsive.

Change Devise Errors

In my application.html.erb file I have
<% flash.each do |key,msg| %>
<div class="message" id="<%= key %>">
<%= content_tag :div, msg %>
</div>
<% end %>
which shows all the notices. Is there a way to add Devise's error be viewed in that notice?
Also, is there a way I can edit the HTML code when there is an error.
When there is an error, it adds a div with an id field_with_errors — can I change that?
I don't know if it's what your looking for, but the config/locales/devise.en.yml allows you to change the content of the messages.
rails generate devise:views will copy Devise's views to your app so you can edit them freely.
https://github.com/plataformatec/devise#configuring-views

Rails 3 - notice and error flash cannot be rendered in a partial

I was trying to clean up application.html.erb, by moving parts of the layout into partials. I had the following code for handling flash errors/notifications:
<div id="flash">
<% if flash[:notice] %>
<h3 class="info_box"><%= flash[:notice] %></h3>
<% end %>
<% if flash[:error] %>
<h3 class="error_box"><%= flash[:error] %></h3>
<% end %>
</div>
This code worked fine in application.html.erb, until I moved it into a file called "_flash.html.erb" and replaced it with the following:
<%= render 'layouts/flash' %>
In the partial the flash hash was not a recognized object and causes a "You have a nil object when you didn't expect it!" error.
I've move the code back to application.html.erb and all is good. But I couldn't find an answer for accessing the flash hash within a partial. Looking at the Rails Guide for "Rendering and Layouts" I can see that there are various ways for render() to pass variables into the partial, but I was unsuccessful in figuring it out. Any ideas?
Goliatone's solution seemed to work, but in the end it didn't. I found out that the reason this was not working for me was that I had named my partial _flash. Apparently Rails creates a local variable for the partial using the partial's name (without the "_" character.) So I had a variable clash. As soon as I change the name of the partial to something other than _flash everything worked perfectly. I found the answer here: Rails flash[:notice] always nil
You can place the conditional check for flash in the layout, and if it exists then render the partial:
<%= render 'layouts/flash' unless flash.nil?%>
Then, if it exists it will get rendered as expected.

Resources