I am attempting to build a simple content management system using Twitter's Bootstrap for a small site and I'm running into an issue with the views.
Rails version is 3.0.10
I want to allow the user to create their own pages so I have a Pages controller that has all your standard RESTful methods. Since these can have crud applied to them, they can only be accessed by a logged-in administrator.
So... I have a Public controller that sets the #pages and #page instance variables and uses those to display them in the public Show view.
Here is the Public controller - pretty simple:
def index
#pages = Page.all
end
def show
#pages = Page.all
#page = Page.find(params[:id])
end
The reason that there is a #pages instance variable on the 'index' method is because I have a welcome page that loads and I'm passing in #pages to populate the navigation elements dynamically:
<div class="nav-collapse">
<ul class="nav">
<li><%= link_to "Welcome", public_index_path, :class => 'active', :id => 'menu_home' %></li>
<% #pages.each do |page| %>
<li><%= link_to page.title, public_path(page) %></li>
<% end %>
</ul>
</div><!--/.nav-collapse -->
The content of the Public controller's 'show' method (which contains an individual page) is passed into the <%= yield %> statement in the applicaton.html.erb file:
<div class="container">
<%= yield %>
<hr>
<footer>
<p>My site</p>
</footer>
</div> <!-- /container -->
So far, this is working fine.
The problem is that when I click the link that takes me to the public_path(page) - I get the content as it should appear, but I lose all my styles. I'm actually getting a 404 error on my stylesheets:
All of these style sheets were loading in just fine on the http://localhost:3000/public page, but when it goes to http://localhost:3000/public/1 - that's when all the styles disappear. But, they are both using the same layout.
Here is what the log file shows when the request is made:
Started GET "/public/1" for 127.0.0.1 at 2012-03-03 21:14:49 -0600
Processing by PublicController#show as HTML
Parameters: {"id"=>"1"}
[1m[35mPage Load (1.0ms)[0m SELECT "pages".* FROM "pages"
[1m[36mPage Load (0.0ms)[0m [1mSELECT "pages".* FROM "pages" WHERE "pages"."id" = 1 LIMIT 1[0m
Rendered public/show.html.erb within layouts/application (24.0ms)
Completed 200 OK in 63ms (Views: 51.0ms | ActiveRecord: 1.0ms)
Started GET "/public/stylesheets/bootstrap.css" for 127.0.0.1 at 2012-03-03 21:14:50 -0600
ActionController::RoutingError (No route matches "/public/stylesheets/bootstrap.css"):
Rendered c:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/actionpack-3.0.10/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (2.0ms)
Started GET "/public/stylesheets/bootstrap-responsive.css" for 127.0.0.1 at 2012-03-03 21:14:50 -0600
ActionController::RoutingError (No route matches "/public/stylesheets/bootstrap-responsive.css"):
Rendered c:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/actionpack-3.0.10/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (1.0ms)
Started GET "/public/stylesheets/elements.less" for 127.0.0.1 at 2012-03-03 21:14:51 -0600
ActionController::RoutingError (No route matches "/public/stylesheets/elements.less"):
Rendered c:/RailsInstaller/Ruby1.9.2/lib/ruby/gems/1.9.1/gems/actionpack-3.0.10/lib/action_dispatch/middleware/templates/rescues/routing_error.erb within rescues/layout (3.0ms)
Thanks for having a look
I managed to find my own answer...
The Rails helper stylesheet_link_tag was generating a relation attribute of type "stylesheet" when the Less css files needed a relation of type "stylesheet/less".
The fix was specifying the relation like this:
<%= stylesheet_link_tag 'elements.less', :rel => 'stylesheet/less' %>
<%= stylesheet_link_tag 'main.less', :rel => 'stylesheet/less' %>
Try to change path to your resource, something like that:
# config/routes.rb
resources :public, :path => :my_public
This will give you routes
public_index GET /my_public(.:format) public#index
POST /my_public(.:format) public#create
new_public GET /my_public/new(.:format) public#new
edit_public GET /my_public/:id/edit(.:format) public#edit
public GET /my_public/:id(.:format) public#show
PUT /my_public/:id(.:format) public#update
DELETE /my_public/:id(.:format) public#destroy
This way it will not mess up with requests to the static assets in public directory. But you may want to rename resource and controller instead.
If you are using the bootstrap-saas gem, make sure you take out the "link href='assets/css/bootstrap-responsive.css' rel='stylesheet'" tag out of your application.html.erb file, this will prevent the helper from generating the relation which results in a routing error.
Related
I have an app that helps a school to track students attendance to sports practices and games, I have all my index actions to render html, csv and xls formats and EVERYTHING GOES WELL. I have a special report that uses several model relations to complete, I am not required to render csv (I think this will be too complex to implement the to_csv method, I don't even have a clue where to put it, but this is not my problem), Now I created the equipos_controller#forma_rep method and a related view with a form to get the report's parameters, as you can see in the routes and controller code, it works fine when the report action renders the default HTML as you can see in the following log, parameters from the 'forma_rep.html.erb' form are in the params array..
Started POST "/equipos/reporte_asist" for 127.0.0.1 at 2017-01-05 18:37:51 -0600
Processing by EquiposController#reporte_asist as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"IP1O2bSgkGcSaUn5Sf9Tnp30yzxfP10+cA0h/1+XudoR7W8SoP6xveP3fwJpLFTvyRaBFdtqsqz5pCfYID5b5Q==", "entrenador"=>"1", "inicio"=>"2016-12-12", "final"=>"2016-12-20", "commit"=>"Crear Reporte"}
... most SQL ommited
Rendering equipos/reporte_asist.html.erb within layouts/application
Rendered equipos/reporte_asist.html.erb within layouts/application (69.4ms)
Rendered layouts/_shim.html.erb (0.5ms)
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
Rendered layouts/_header.html.erb (5.9ms)
Rendered layouts/_footer.html.erb (1.1ms)
Completed 200 OK in 210ms (Views: 165.2ms | ActiveRecord: 5.6ms)
But when I click the "Excel" link :
Started POST "/equipos/reporte_asist.xls" for 127.0.0.1 at 2017-01-05 18:37:56 -0600
Processing by EquiposController#reporte_asist as XLS
Parameters: {"authenticity_token"=>"oYVjNfxN5Qxt9FHC6PpeU0wQenD3p+otaxcGts1kZRuQlUL+6 BPE1pxqZznIKVkiGPIwWXPyBb/ivgCRss2HJA=="}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
Equipo Load (0.2ms) SELECT "equipos".* FROM "equipos" WHERE "equipos"."user_id" = ? [["user_id", 1]]
Completed 500 Internal Server Error in 11ms (ActiveRecord: 0.4ms)
NoMethodError (undefined method `<<' for nil:NilClass):
app/controllers/equipos_controller.rb:96:in `block in reporte_asist'
app/controllers/equipos_controller.rb:95:in `reporte_asist'
I can see that the parameters are not complete when I click the Excel link in the html file, how can I send them again? my routes work fine with the html version and the #index action renders fine in all formats, please help me.
Here is all code involved.
Routes:
resources :categorias
get '/equipos/forma_rep'
post '/equipos/reporte_asist', to: 'equipos#reporte_asist', as: 'reporte_asist'
resources :equipos
resources :players
app/controllers/equipos_controller.rb
def index
#equipos = Equipo.paginate(page: params[:page])
respond_to do |format|
format.html
format.csv { send_data #equipos.to_csv }
format.xls
end
end
# GET /equipos/forma_rep
def forma_rep
#equipo = Equipo.new
#entrenadores = User.all
end
# PUT /equipos/reporte_asist
def reporte_asist
if params[:entrenador]
#entrenador = User.find(params[:entrenador].to_i)
inicio = Time.parse(params[:inicio])
final = Time.parse(params[:final])
#equipos = #entrenador.equipos
#eventos = reporte(#entrenador.id, inicio, final)
else
#entrenador = current_user
#equipos = #entrenador.equipos
#equipos.each do |equi|
#eventos << equi.eventos
end
end
respond_to do |format|
format.html
format.xls
end
end
I have created the app/views/equipos/reporte_asist.xls.erb file with the XML directives as in..
<?xml version="1.0"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Worksheet ss:Name="Asistencias">
<Table>
<Row>
<Cell><Data ss:Type="String">Entrenador:</Data></Cell>
<Cell><Data ss:Type="String"><%= #entrenador.name %></Data> </Cell>
</Row>
....etc.
And this is the link I have in the app/views/equipos/reporte_asist.html.erb
<p>
Descargar:
<%= link_to "Excel", reporte_asist_path(format: "xls"), method: :post %>
</p>
Of course I have defined the Mime:Type.register in the config/initializers/mime_types.rb and requested the 'csv' library in my config/application.rb . I am using Rails 5.0.0.1 and Ruby 2.3.1 ...
This is the code that collects report parameter from user, it is inside the app/views/equipos/forma_rep.html.erb that posts to the reporte_asist.html.erb:
<h1>Reporte de Asistencias</h1>
<%= form_tag(reporte_asist_path) do %>
<%= label_tag(:entrenador, "Entrenador:") %>
<%= select_tag :entrenador, options_from_collection_for_select(#entrenadores, "id", "name"), prompt: "Seleccione el entrenador", class: 'form-control' %>
<%= label_tag(:inicio, "Fecha inicial de reporte:") %>
<%= date_field_tag :inicio, class: 'form-control' %>
<%= label_tag(:final, "Fecha final de reporte:") %>
<%= date_field_tag :final, class: 'form-control' %>
<%= submit_tag "Crear Reporte", class: "btn btn-default" %>
<% end %>
</div>
Initially this is the code that sends the report parameters, but once in the report view I cannot (and don't want to) re-render the form, that's why I put the link_to to the same controller but trying to render the excel
Add the parameters you want to POST to your reporte_asist_path helper, like this:
reporte_asist_path(format: 'xls', entrenador_id: #entrenador.id)
More information can be found here:
http://api.rubyonrails.org/classes/ActionDispatch/Routing/UrlFor.html#method-i-url_for
Also note that while using POST method for links is supported by Rails, it relies on JavaScript. If the user has JavaScript disabled, the request will fall back to GET method. So it's safer to use forms.
I am trying to display a collection as a partial ( on a side panel). I get an error above, have been fighting for several hours and do not understand what is the problem.
Containing view (a partial template included into application.html.haml file):
%span.span12
%ul.nav.nav-pills.nav-stacked{style: "color: white;"}
= render :partial => 'categories/categories_list'
Partial /categories/_category_list.html.haml:
%ul
- #categories.each do |category|
%li{style: "color: white;"}=category.name
Controller (categories_controller):
class Macro::CategoriesController < ApplicationController
def categories_list
#categories= Category.all
end
end
I have separately tried to add "collection: #categories" as an option for render :partial - to non avail. When I replaced the instance variable with just an array in order to test the partial rendering, it worked ( the list items got rendered). Seem like the variable #categories does not get instantiated, however I have double-checked in console that a given activerecord query returns a set of objects. I am breaking my brain to see where I made a mistake.
Log:
Started GET "/ios/macro/namespace2/another" for 127.0.0.1 at 2014-02-11 11:41:23 +0100
Processing by Macro::Namespace2::AnotherController#index as HTML
Parameters: {"param1"=>"xx"}
....... (SQL queries for that view)
Rendered macro/namespace2/another_controller/_another_view.html.haml (7.0ms)
Rendered macro/namespace2/another_controller/index.html.haml within layouts/application (29.6ms)
Rendered layouts/_logout_link.html.haml (0.5ms)
Rendered layouts/_top_navigation.html.haml (3.3ms)
Rendered layouts/_search.html.haml (0.8ms)
Rendered macro/categories/_categories_list.html.haml (0.8ms)
Rendered macro/_navigation.html.haml (3.6ms)
Completed 500 Internal Server Error in 49ms
ActionView::Template::Error (undefined method `each' for nil:NilClass):
1: %ul
2: - #categories.each do |category|
3: %li{style: "color: white;"}=category
app/views/macro/categories/_categories_list.html.haml:2:in `_app_views_macro_categories__categories_list_html_haml__246519878332953677_70248836672780'
app/views/macro/_navigation.html.haml:11:in `_app_views_macro__navigation_html_haml__3071184578230019020_70248793690940'
app/views/layouts/application.html.haml:24:in `_app_views_layouts_application_html_haml__3208937943371424843_70248793607300'
Rendered /Users/me/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_trace.erb (1.1ms)
Rendered /Users/me/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb (0.8ms)
Rendered /Users/me/.rvm/gems/ruby-2.0.0-p353/gems/actionpack-4.0.0/lib/action_dispatch/middleware/templates/rescues/template_error.erb within rescues/layout (10.6ms)
Routes:
namespace "macro" do
namespace "namespace2" do
resources :another, only: [:index]
end
resources :categories
end
end
Probably the #categories_list action in Macro::CategoriesController is not being called. Check the log and see which controller and action is handling the request.
You should see something like:
'Processing by Macro::CategoriesController#categories_list as HTML'
'Parameters: { }'
Thank you for allowing me here. I have searched and searched for the answer to this riddle.
I am trying my first Rails app, and everything is straightforward: the index page summons a _calc.html.erb partial. And summons it, and summons it...
ETA FIXED! CODE BELOW -> the offending line is highlighted for those who encounter the error in the future:
<%= form_for :plan do %>
<em>OK, how much do you make?</em>
<%= number_field_tag :salary %>
<% puts "The salary field is producing the loop" %>
<h3><span id="more">Continue</span></h3>
<script type="text/javascript">
$("#more").click(function(){
$("div.subcalculator").animate({opacity: 1},800);
});
$("#moremore").click(function(){
**<% if check_expenses(:salary, :weeklyExpenses) %>**
$("div.sub_subcalculator").animate({opacity: 1},800);
**<% end %>**
});
</script>
<div id="subcalculator" class="subcalculator">
ETA ERROR: The screen that now comes up on localhost:3000 is
We're sorry, but something went wrong.
If you are the application owner check the logs for more information.
And in the Rails Server it says:
Started GET "/" for 127.0.0.1
at 2013-11-03 11:30:37 -0500 Processing by IntroController#index
as HTML The salary field is producing the loop The salary
field is producing the loop The salary field is producing the
loop The salary field is producing the loop The salary field
is producing the loopRendered plan/_calc.html.erb (1.3ms)
Rendered plan/_calc.html.erb (2.2ms) Rendered
plan/_calc.html.erb (3.1ms) Rendered plan/_calc.html.erb
(4.0ms) Rendered plan/_calc.html.erb (4.8ms) Rendered
plan/_calc.html.erb (5.6ms) Rendered plan/_calc.html.erb
(6.5ms) Rendered plan/_calc.html.erb (7.4ms) Rendered
plan/_calc.html.erb (8.2ms) Rendered plan/_calc.html.erb
(9.1ms)
I did ascertain the loop occurs in the top of the partial; the first helper is for a number_field_tag and that seems to render over and over but the subsequent number_field_tag(s) do not. I tend to compulsively rake the routes and migration if I've made even tiny changes, so if that helps at all:
root GET / intro#index
intro_index GET /intro/index(.:format) welcome#index
plan_index GET /plan(.:format) plan#index
POST /plan(.:format) plan#create
new_plan GET /plan/plan/calc(.:format) plan#new
edit_plan GET /plan/:id/edit(.:format) plan#edit
plan GET /plan/:id(.:format) plan#show
PATCH /plan/:id(.:format) plan#update
PUT /plan/:id(.:format) plan#update
DELETE /plan/:id(.:format) plan#destroy
Very simple process I'm trying to implement.
On a home page or landing page I want to capture emails for an email list.
If the email passes validation, it gets saved, Great! Everything works fine when there are no errors.
When there is an error like only inputting an 'a' character as shown in the log below. Or even just an empty string I continually get the same TypeError (can't convert nil to String)
Here is the log:
Started GET "/" for 127.0.0.1 at 2013-06-13 13:48:56 -0400
Connecting to database specified by database.yml
Processing by HighVoltage::PagesController#show as HTML
Parameters: {"id"=>"home"}
Rendered shared/_error_messages.html.erb (0.4ms)
Rendered layouts/_visitor_form.html.erb (7.9ms)
Rendered pages/home.html.erb within layouts/application (13.1ms)
Completed 200 OK in 82ms (Views: 39.6ms | ActiveRecord: 1.8ms)
[2013-06-13 13:48:57] WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true
Started POST "/visitors" for 127.0.0.1 at 2013-06-13 13:48:59 -0400
Processing by VisitorsController#create as HTML
Parameters: {"utf8"=>"✓",authenticity_token"=>"esTPNzNtkmNPTe7Jh+E2aDHNrgocU5Z8g49Nj0QiOhQ=", "visitor"=>{"email"=>""}, "commit"=>"Add to newsletter list"}
(0.1ms) begin transaction
Visitor Exists (0.2ms) SELECT 1 AS one FROM "visitors" WHERE LOWER("visitors"."email") = LOWER('') LIMIT 1
(0.1ms) rollback transaction
Completed 500 Internal Server Error in 39ms
TypeError (can't convert nil into String):
app/controllers/visitors_controller.rb:12:in `create'
Here is the visitors_controller.rb
def create
#visitor = Visitor.new(params[:visitor])
if #visitor.save
flash[:success] = "Your email has been added!"
redirect_to '/'
else
render '/'
end
end
I've also tried
#visitor = Visitor.new(:visitor => params[:visitor][:email])
and a few other sequences with no success.
How can I get the unsuccessful saves to gracefully show the validation errors and allow the user to resubmit.
Here is the layout:
<%= form_for Visitor.new do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.submit "Add to newsletter list", class: "btn btn-large btn-primary" %>
<% end %>
Maybe the high_voltage gem is screwing me up. I don't have enough experience to know.
UPDATE:
rake routes
visitors POST /visitors(.:format) visitors#create
home /home(.:format) pages#home
root / high_voltage/pages#show {:id=>"home"}
page GET /pages/*id high_voltage/pages#show
The problem is, render '/' does not render index page. You have to specify which action page you want to be rendered. According to your routes, this line should look like this:
render 'pages/home'
I am developing a rails application which should send push notifications to iOS devices. I am using apn_on_rails gem. Everything works fine in the rails console. However when I run the server, I get undefined method errors for all the basic view methods such as content_for or form_tag etc:
When I take require 'apn_on_rails' from my development.rb out, the views work again, but of course without push notifications.
Here is an example trace:
Processing DashboardController#index (for 127.0.0.1 at 2011-02-27 13:55:59) [GET]
User Load (0.2ms) SELECT * FROM "users" WHERE ("users"."id" = 1)
CACHE (0.0ms) SELECT * FROM "users" WHERE ("users"."id" = 1)
Rendering template within layouts/dashboard
Rendering dashboard/index
ActionView::TemplateError (undefined method `content_for' for #<ActionView::Base:0x103343970>) on line #1 of app/views/dashboard/index.html.erb:
1: <% content_for :header do %>
2: <%= render :partial => "header", :locals => {:title => "Dashboard"} %>
3: <% end %>
app/views/dashboard/index.html.erb:1
app/controllers/dashboard_controller.rb:6:in `index'
Rendered rescues/_trace (28.5ms)
Processing ApplicationController#index (for 127.0.0.1 at 2011-02-27 13:55:59) [GET]
ActionView::TemplateError (undefined method `debug' for #<ActionView::Base:0x103343970>) in /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/templates/rescues/_request_and_response.erb:
Rendered rescues/_trace (24.0ms)
/!\ FAILSAFE /!\ Sun Feb 27 13:55:59 +0100 2011
Status: 500 Internal Server Error
ActionView::TemplateError (undefined method `debug' for #<ActionView::Base:0x1031eaad8>) in /Library/Ruby/Gems/1.8/gems/actionpack-2.3.8/lib/action_controller/templates/rescues/_request_and_response.erb:
In /library/ruby/gems/1.8/gems/actionpack-2.3.8/lib/action_controller/templates/rescues/_request_and_response.erb
Thanks for any help...
It is not evident whether you call config.gem 'apn_on_rails' - it sounds more like you are require:ing the library, which probably is something you should not do at this point: the point of environment setup.
Have the config.gem things in your environment setup (i.e. development.rb), but make eventual requires happen later (->in the controller / model / helper in question).