Rails page has wrong html - html

I have a link to a page in the same folder as this page on my rails site:
<%= link_to 'Special Access', 'followers/special_access' %>
However, when I go to this page it shows a different page on that url.
<p id="notice"><%= notice %></p>
<div id="sent">
<p>Your request has been sent</p>
<%= link_to 'Home', followers_path %>
</div>
I tried deleting the page that the html is from, but first of all I need that page and it also gives me an error.
I edited the controller to contain:
def special_access
format.html { redirect_to followers/special_access }
format.json { render :json => #post }
end
instead of
def show
but that still didn't solve the problem.
How do I get the right html to show up on the right page?

If you do not define a route for special_access, rails will just assume the the special_acces part in the path is the :id of the route for the show page (as the urls look like followers/:id).
So first off, in your routes.rb, find the resources :followers and replace with the following:
resources :followers do
collection do
get :special_access
end
end
And now you should best always use the rails path helpers, so your link would become
<% link_to 'Special Access', special_access_followers_path %>
Here I was assuming the special access is on the collection of the followers, if it should be on a specific follower (which seems more logical to me, but I have no idea of course), you should write
resources :followers do
member do
get :special_access
end
end
And your link would become
<% link_to 'Special Access', special_access_followers_path(#follower) %>
I am not quite sure what you want to do in your controller action, I hope you just want to render an html page (because redirecting to the same url seems silly, and your syntax is wrong there too).
Hope this helps.

Related

Ruby On Rails: +1 option/vote button error

I'm learning ROR and working on a voting style application, I've got my four tables up and running Users, Questions, Options and Answers and I can write to the Answers table via MySQL and the total votes are displaying so far which is great.
I'm having a problem with getting a +1 button working (eventually it'll be unique per user but for now I just want to see it working).
I'm fairly certain my files are all setup correctly but I'm confused with what to put in my Questions "Show" view for the button, it might be a routes problem as it does say undefined method 'upvote_option_path' - any help would be greatly appreciated! If I've forgotten any files below let me know :-)
Question's Show View:
<% #question.options.each_with_index do |option, index| %>
<p><%= option.option_text %></p>
<p><%= pluralize(option.answers.count, "vote") %><br><br></p>
<p><%= button_to '+1', upvote_option_path(option), method: :post %></p>
<% end %>
Option's Controller upvote:
def upvote
#question = Question.find(params[:question_id])
#option = Option.find(params[:option_id])
Answer.create(user_id: current_user.id, question_id: #question, option_id: #option)
end
Routes file:
resources :questions do
resources :options do
post 'upvote'
end
end
rake routes:
question_option_upvote POST /questions/:question_id/options/:option_id/upvote(.:format) options#upvote
undefined method upvote_option_path
According to your routes, there is no upvote_option_path, it should be question_option_upvote_path. Also the path takes two arguments as keys(:question_id & :option_id), so you need to pass those two to the path.
The below should work
<%= button_to '+1', question_option_upvote_path(#question, option), method: :post %></p>
In rake routes you have this: question_option_upvote, in your view you have this: upvote_option_path. Pretty sure your view should say question_option_upvote_path(option).

Flash message from controller: its html-code is displayed as text

In my controller, as part of the create method, I have a flash message:
flash[:success] = "An email was sent to #{#user.email}. Please check your inbox. <br> If you find this email in your junk mail folder, please mark the email as 'Not Junk'.".html_safe
The <br> in the middle however is displayed as text instead of that it processes it as html code and continues the text on a new line. This despite the use of html_safe at the end. Does anyone know what could be causing this and what to do about it?
Update: I tried it in other controller flash messages also. Just added <br> and html_safe to see how it would display and each time it caused problems. While in view pages, it doesn't generate any problems.
As requested the code that displays the flash messages (but even if I reduce this to just <%= message %> the problem still persists):
<% flash.each do |message_type, message| %>
<%= content_tag :div, class: "alert alert-#{message_type}" do -%>
<%= message %>
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<% end -%>
<% end %>
<%= message.html_safe %>
This will silently put all notices straight into html, so you don't really want to do this. You can do this if, and only if you are 100% sure, that your app never ever puts any user content in notices, or your app will be vulnerable to js injection attack. Instead try:
Flash message with html_safe from the controller in Rails 4 (safe version)
So yes, add before_filter -> { flash.now[:success] = flash[:success].html_safe if flash[:html_safe] && flash[:success] } to your ApplicationController, and than, any time you set html safe flash[:success] also set flash[:html_safe] to true, like
flash[:success] = "An email was sent to #{#user.email}. Please check your inbox. <br> If you find this email in your junk mail folder, please mark the email as 'Not Junk'.".html_safe
flash[:html_safe] = true
Edit: Yes, you can skip .html_safe at the end. You can make it more generic and remove unnecesary message like
before_filter -> {
if flash[:html_safe]
flash.delete(:html_safe)
flash.each do |k, message|
flash[k] = message.try(:html_safe)
end
end
}
Hopefully #nextstep reads this an undeletes his answer because he was spot on.
You need to do the .html_safe in the display of your flash message, not when you set them because in between those things the message will be serialized to the session and so will lose the html_safe flag.
I screwed up in my testing because I was setting and displaying the flash message in the same request (and so it hadn't been serialized/deserialized in between being set and displayed).
So, as #nextstep originally said (basically), change your view to:
<%= message.html_safe %>

Rails div not rendering?

I have a simple app I'm following from a textbook. It's a store app and on the oft side of the page a shopping cart is shown. However, when the cart is empty it is supposed to be hidden. So I wrote a helper function to hide the cart whenever it is empty. This would have been east enough just to do in the html but it's how the book shows it. It works mostly. If I empty the cart it stops being displayed, but when I first open the page the cart will be invisible even if its not empty! Adding an item to it will then reveal it.
Here's the code:
application.html.erb
<div id="cart">
<% if #cart %>
<% hidden_div_if( #cart.line_items.empty?, id:"cart" ) do %>
<%= render #cart %>
<% end %>
<%end%>
</div>
application_helper.rb
module ApplicationHelper
def hidden_div_if(condition, attributes = {}, &block)
debugger
if(condition)
attributes["style"] = "display: none"
end
content_tag("div", attributes, &block)
end
end
Where I put the debugger statement, I checked the condition and it says it's false. So, I thin it's an issue with the html file. The controller sets the cart before hand with this code at the top.
include CurrentCart
before_action :set_cart
So, I'm not sure why it would show after a button is pressed but not on the initial page load. Any ideas?
thanks
You need to start with <%= in erb if you want to output the return value of a helper method. Change the line in which you call your helper method to:
<%= hidden_div_if(#cart.line_items.empty?, id: "cart") do %>

Render Partial Help and Breakdown

When a person uses:
<%= render user.posts %>
what is happening behind the code that is tells it to search for the partial _post.html.erb and know to pass the a specified user inside the call?
I have seen many example where a partial is called from outside the index, such as:
<%= render partial: "posts", locals: {post: post} %>
But that is different from the example above
render user.posts detects a model/s as a parameter, and searches for /posts/_post.html.erb partial, see here, section 3.4.5.
render :partial => 'xxx/yyy' searches xxx/yyy file in views path app/views, i.e. app/views/xxx/yyy, you can see in which places these views are searched by looking at your rails server console.
Figured out what I was trying to achieve. I knew I was missing some simple.
Inside my show view:
<% #user.posts.each do |post| %>
<%= post.title %>
<% end %>

Rails - How do you render the html version of a view in one link, and the json.builder version in another link?

I am fairly new to Ruby on Rails but I have been dabbling at a toy app (Practice Management), for practice.
I was able to render a fullcalendar-rails version of my appointments successfully for one link(using appointments_path, and a .json.jbuilder file). However, I now want a list version of the appointments index in html format but I can't seem to find an answer online.
I still want to use the same path (appointments_path), and the same information but with a different format.
Any help is very much appreciated!
Here is my code:
appointments_controller.rb
def index
#appointments = Appointment.all
respond_to do |format|
format.json
format.html
end
end
index.json.jbuilder
json.array! #appointments do |appointment|
json.start appointment.starts_at
json.title appointment.patient.initials
json.url edit_appointment_url(appointment.id)
end
index.html.erb
<div class="appointments-index" id="appointments-index-body">
<% if current_user.appointments.empty? %>
You have no scheduled appointments.
<% else %>
<div id='appointments' class="appointments-body">
<div>
<% end %>
</div>
After implementing appointments_path(format: :json) to either the link for a simple list or the fullcalendar-rails, I got this:
[{"start":"2014-02-13T14:45:00.000Z","title":"Beast, A.","url":"http://localhost:3000/appointments/112/edit"},{"start":"2014-02-
13T16:00:00.000Z","title":"Beast, A.","url":"http://localhost:3000/appointments/113/edit"}, {"start":"2014-02-13T15:00:00.000Z","title":"Beast, A.","url":"http://localhost:3000/appointments/114/edit"},{"start":"2014-02- 13T15:15:00.000Z","title":"Beast, A.","url":"http://localhost:3000/appointments/115/edit"}, {"start":"2014-02-18T10:15:00.000Z","title":"Beast, A.","url":"http://localhost:3000/appointments/116/edit"},{"start":"2014-02- 13T11:00:00.000Z","title":"Beast, A.","url":"http://localhost:3000/appointments/117/edit"}]
providing the id='appointments' in the after else makes sure that fullcalendar-rails will be applied in this div.
Please let me know if there's any info I could add to make this clearer. Thanks!
You can specify format in url helper, like this:
appointments_path(format: :json)
Hope this helps :)