Ruby on Rails - Ruby code in view file gets printed - html

I have a Rails 3 project in Aptana Studio 3 with a html.erb view file containing the following code:
<% if #books.blank? %>
<p>
There are not any books currently in the system.
</p>
<% else %>
<p>
These are the current books in our system
</p>
<ul id="books">
<% #books.each do |c| %>
<li>
<%= link_to c.title, {:action => 'show', :id => c.id} -%>
</li>
<% end %>
</ul>
<% end %>
<p>
<%= link_to "Add new Book", {:action => 'new' }%>
</p>
Then in the embedded terminal, I run rails server, click the "Run with Firefox Server" button in Aptana which opens the application with firefox, and directs me to this link: http://127.0.0.1:8020/library/app/views/book/book.html.erb
The problem is that I get this output:
<% if #books.blank? %>
There are not any books currently in the system.
<% else %>
These are the current books in our system
<% #books.each do |c| %>
<%= link_to c.title, {:action => 'show', :id => c.id} -%>
<% end %>
<% end %>
<%= link_to "Add new Book", {:action => 'new' }%>
Seems like the ruby code isn't getting evaluated but rather printed, however the syntax looks alright to me... Does anyone know what might be the problem?

Aptana doesn't open the right page. If you're just using the default server, then you probably want to open localhost:3000.
Some more info: look at the url, it's just the path to a file, not the url for the books index.
Your file path (http://127.0.0.1:8020/library/app/views/book/book.html.erb) also seems strange...
First, the book folder name should be plural (app/views/books). And second, your view code seems like it's the books index page, so it probably should be in app/views/books/index.html.erb.

Related

Remove unexpected content on a website

While following a tutorial on building a Ruby-on-Rails blogging website, I'm running into some unexpected results. The project so far is stored on https://github.com/khpeek/jumpstart-blogger.
The main page is an "Articles" page, which looks like this:
So far, so good (except for the somewhat curious position of the "Create a New Article" button, which used to be directly below the articles).
The appearance of "All Articles" is governed by app/views/articles/index.html.erb, which reads
<h1>All Articles</h1>
<ul id="articles">
<% #articles.each do |article| %>
<li>
<%= link_to article.title, article_path(article), class: 'article_title' %>
</li>
<% end %>
</ul>
<%= link_to "Create a New Article", new_article_path, class: "new_article" %>
The h1 heading is the first thing in the .html.erb file, and also the first thing that appears on the web page.
However, if I click on an article link, say "Article with Ruby Tag", I see the page below:
Besides the desired box with the article, tags, and comments, there are also two submit buttons and "<< Back to Articles List" buttons which are neither desired nor expected.
The appearance of this page is governed, as I understand it, by app/views/articles/show.html.erb, which reads
<h1><%= #article.title %></h1>
<p>
Tags:
<% #article.tags.each do |tag| %>
<%= link_to tag.name, tag_path(tag) %>
<% end %>
</p>
<% if #article.image.exists? %>
<p><%= image_tag #article.image.url %></p>
<% end %>
<p><%= #article.body %></p>
<h3>Comments (<%= #article.comments.size %>)</h3>
<%= render partial: 'articles/comment', collection: #article.comments %>
<%= render partial: 'comments/form' %>
<%= link_to "<< Back to Articles List", articles_path %>
<% if logged_in? %>
<%= link_to "delete", article_path(#article), method: :delete, data: {confirm: "Really delete the article?"} %>
<%= link_to "edit", edit_article_path(#article) %>
<% end %>
The first line in this file is the h1 header, but the 'unexpected' contents seems to come before that. So I'm having trouble seeing where to start to remove this content. Any pointers?
You're dealing with layout Rails' concept. Read this.
Anyway, you probably have a layout file in app/views/layouts.
check your application.html.erb in layouts folder.. it is rendering in header on some condition

Rendering view for an element in rails by :id

I have a sidebar that contains links to all of a users :shopping_lists. Upon clicking on one of those links, I'd like to render a page showing the :list_items in that particular list. Here's my sidebar partial:
<aside class="sidebar-nav-fixed">
<h1>My Lists</h1>
<% if user_signed_in? %>
<% current_user.shopping_lists.each do |l| %>
<ul>
<%= link_to "#{l.name}", '#' %>
</ul>
<% end %>
<% else %>
<h5><%= link_to "Sign in to manage lists.", new_user_session_path %></h5>
<% end %>
</aside>
My question is: what path would I be putting in place of my current stub link in order to route to the correct list? Thanks in advance!
That will depend on how your routes are setup. I would expect shopping lists to always be in the context of a user, so probably something like this:
<%= link_to l.name, user_shopping_list_path(current_user, l) %>
If shopping lists are a top level route, then probably something like this:
<%= link_to l.name, shopping_list_path(l) %>
There are couple of things you can do, granted your routes are setup correctly:
The easiest is:
link_to "#{l.name}", l
Rails should create a link something similar to http://host/shopping_lists/2
The above is a shorthand for
link_to "#{l.name}", shopping_list_path(l)
To see a list of available routes and methods you can run:
bundle exec rake routes
in the root of your rails app

Spree User information

I'm using Spree as an eCommerce solution for a website that I am building and need to customize the layout, the deface option is great but I already have a layout for the rest of my application that I want to use so there is no change between the main part of my site and the store.
Having looked through the spree source code I have been able to transfer most of the infrastructure over to my own new template but I have hit one stumbling block. In the default template above the search box there are login/account and logout links which based on some digging through the code is rendered in the 'header' partial which itself renders the nav bar which renders the search bar partial, and the main nav bar which shows the links to home and the shopping cart, but nowhere mentions the user in/out stuff. Commenting out the rendering of the header partial removes all of this stuff but also the user information, which as far as I can tell isn't mentioned anywhere...
Does anyone know where in the default spree layout it implements this code for showing a login/logout account link, I could do this relatively simply with basic links to it but would rather understand how Spree implements this itself and I'm trying to keep my layout compatible with any updates to the core code.
Any help would be greatly appreciated, thanks!
Edited: For clarity
On version 3.0.1 of Spree and maybe on other older versions the user functionality is not handled by the core itself. Users are handled by the Spree Auth (Devise) Spree extension. This extension is included by default on new Spree apps. The extension uses a deface override to add this functionality. Interestingly enough the partial used by this override is not on the extension itself but rather on the Spree frontend files. I assume to make this component reusable should you wish to implement your custom user module. This is the code of the partial:
<% if spree_current_user %>
<li><%= link_to Spree.t(:my_account), spree.account_path %></li>
<li><%= link_to Spree.t(:logout), spree.logout_path %></li>
<% else %>
<li id="link-to-login"><%= link_to Spree.t(:login), spree.login_path %></li>
<% end %>
Found code in the RDR theme that explains this, still not sure why it doesn't show up in the default spree code, maybe a data hook?
The way RDR does it:
<% if current_user %>
<%= link_to t('logout'), destroy_user_session_path, :class => "cart" %>
<%= link_to t('my_account'), account_path, :class => "cart" %>
<% else %>
<%= link_to t('log_in'), login_path, :class => "cart" %>
<% end %>
override menu with
<% if current_user %>
<%= link_to t(:logout), spree.destroy_user_session_path %>
<%= link_to t(:my_account), spree.account_path %>
<% else %>
<%= link_to t(:login), spree.login_path %>
<% end %>
As of Spree 2.3.2 same thing can be done with:
<h2>Your Account</h2>
<ul>
<% if spree_current_user %>
<li><%= link_to t('My Account'), account_path, :class => "cart" %></li>
<% else %>
<li><%= link_to t('Log In'), login_path, :class => "cart" %></li>
<li><%= link_to t('Sign Up'), registration_path, :class => "cart" %></li>
<% end %>
</ul>

Inserting rails into HTML file

When writing an HTML file, why use <%= INSERT RAILS HERE %> vs. <% INSERT RAILS HERE %>
<%= %> emits a string, <% %> runs code.
On the pedantic side, you're writing an ERb template, not an HTML file--the syntax is the same whether it's a template for HTML, JS, or whatever.
The ERB docs provide additional (but not complete) information.
<%= %> will return value and display in your page. Assume that you have person.name = 'Dark'
<%= person.name %>
will display Dark in your web page.
<% %> will not return any value to your page. It just embed simple ruby code. Usually used with `control statement'.
<% if person.present? %>
<span><%= person.name %></span>
<% end %>
When we use <%= %> it simply displays the value returned, on the html page.
<% %> executed the code but doesn't dispaly it on the html page.

Placing link at top

How do I place a link at the top of my page when the URL that it is pointing to is not determined until later down the page. In this example, I want to move Create and Edit Scenario links to the top of the page, but as you can see Edit Scenario depends on knowing the #scenario_id first.
<%= will_paginate #scens, :next_label => 'Older', :prev_label => 'Newer' %>
<div class="box">
<% for scenario in #scens %>
<% #created = scenario.created_at %>
<% #updated = scenario.updated_at %>
<% #scenario_id = scenario.id %>
<% if scenario.scenario_image.exists? %>
<%= scenario_image_tag(scenario) %>
<% end %>
<%= simple_format(scenario.description) %>
<% end %>
</div>
<% if session[:role_kind] == "controller" %>
<p>
<%= button_to "Create new scenario", :action => "create" %>
<% if #scens.size > 0 %>
<%= button_to "Edit scenario", :action => "edit", :id => #scenario_id %>
<% end %>
</p>
You can add the link at the top but you will need to programmatically access it later and then assign the URL to it. That needs some kind of reference or look-up capability, I'm thinking client-side javascript but that's as I don't know Ruby.
Alternatively you could create the link later when you have the URL and place the link at the top using CSS positioning. The actual position of all the DOM elements on the page need not match the order in which they are rendered.
One way to do this is to use a helper:
In your helper.rb file:
def stack_example(scens, &block)
html = 'Scenario Details'
edit_link = 'Edit Link'
yield html, edit_link
end
Then in your partial you could have something like:
<% stack_example(#scens) do |html, edit_link| %>
<%= edit_link %><br>
<%= html %>
<% end %>
Should output the following:
Edit Link
Scenario Details
I don't get it. Why do you create model in the view layer? Why wouldn't you create the model variables in the controller? Sth like:
class your_controller
def your_method
#scenario_id = ...
end
end
I think that your problem lays in the invalid MVC usage. Don't you think that all the #member #variables should be initialized before the view starts to render?