How to add new view to Ruby on Rails Spree commerce app? - ruby-on-rails

A very basic question that I cannot seem to solve is how to add a new view to my Ruby on Rails Spree commerce application. What I want to do is have a link next to the Home link in the _main_nav_bar.html.erb and when you click it have displayed an about page at the place where the products are displayed. So:
home about cart
---------------------
things of the HOME page
---------------------
footer
Click on about leads to:
home about cart
---------------------
things of the ABOUT page
---------------------
footer
In views/shared/_main_nav_bar.html.erb the link I created (based on the home link) looks as follows:
<li id="home-link" data-hook><%= link_to Spree.t(:home), spree.root_path %></li>
<li id="about-link" data-hook><%= link_to Spree.t(:about), spree.about %></li>
The AboutController I created looks as follows:
module Spree
class AboutController < Spree::StoreController
def index
end
end
end
And finally, in config/routes.rb I added the following code:
root :about => 'about#index'
When I now try to start the server it just does not work anymore without giving an error message.
Can someone please help me out on this issue? How do I add a view and create a working link that loads in the main div?
EXTRA: routes.rb
MyStore::Application.routes.draw do
mount Spree::Core::Engine, :at => '/'
Spree::Core::Engine.routes.prepend do
#get 'user/spree_user/logout', :to => "spree/user_sessions#destroy"
end
get '/about' => 'spree/about#index'
get '/contact' => 'spree/contact#index'
end

You need to do in routes.rb:
Spree::Core::Engine.routes.prepend do
get '/about', :to => 'about#index', :as => :about
end
or without the Spree::Core scope:
get '/about', :to => 'spree/about#index', :as => :about
Because, you have your about_controller.rb i.e. AboutController defined inside Spree module. And, hence you'll have to reference the spree namespace in your route to set it properly.
In your views:
<li id="about-link" data-hook><%= link_to Spree.t(:about), spree.about_path %></li>
or
<li id="about-link" data-hook><%= link_to Spree.t(:about), main_app.about_path %></li>

Related

How can i route a mothod for more than one controller rails 6

i have this in my routes.rb
get "invoices/log_out" => "users#logout", :as => "log_out"
this seems to work only in localhost:3000/invoices/new/log_out
as when i am at localhost:3000/invoices and i click on log out i have the following error
No route matches [GET] "/log_out"
so i want to make it work in all my controllers were are five
something like get "all_controllers/log_out" => "users#logout", :as => "log_out"
<nav class="navi_me">
<ul>
<li>Εισαγωγη Προμηθευτη</li>
<li>Προμηθευτες</li>
<li><a href='/items'>Προϊόντα</a></li>
<li><a href='/items/insert'>Εισαγωγη Προϊόν</a></li>
<li><a href='/invoices'>Τιμολόγια</a><li>
<li><a href='/invoices/new'>Εισαγωγη Τιμολόγιου</a><li>
<li><a href='/pbinvoices'>Πιστωτικά Τιμολόγια</a><li>
<li><a href='/pbinvoices/new'>Εισαγωγη Πιστωτικου Τιμολόγιου</a><li>
<li><a href='/census'>Απογραφες</a><li>
<li><a href='/users/setting'>User Setting</a></li>
<li>Αποσύνδεση</li>
</li>
</ul>
</nav>
```
def logout
session[:user_id] = nil
redirect_to users_login_path , :notice => "Logged out!"
end
Looking at your route:
get "invoices/log_out" => "users#logout", :as => "log_out"
When someone hits localhost::3000/invoices/log_out it routes the request to the logout method on your UsersController. Changing the path part to 'all_controllers/log_out' won't change anything about the behaviour of your app other than change the text of the path. It doesn't really matter to your problem, but since logging out is a single global operation, you're probably better off with just '/log_out' as the route path to keep things simple.
You didn't include any snippets of your view code, but your problem is almost certainly in how you're specifying the link_to. The :as => "log_out" part of your route defines an alias for the route. Rails creates URL helpers automatically using that alias (log_out_path and log_out_url) that you can use in your views and controllers to link to that operation:
<%= link_to "Logout", log_out_path %>
Using the URL helpers ensures that your code is using right route even if you later change the actual path in routes.rb.

Rails[Devise]: devise breaking navbar links

I have a Bootstrap navbar, but the tabs are generated at runtime. It's this way because they link to show/:id and a user can delete the record associated with that tab at any time. I created the links like this:
<% #groups.each do |group| %>
<li id=<%= group.id %>><%= link_to t("navbar." + group.name.singularize.downcase), :controller => 'groups', :action => 'show', :id => group.id %></li>
<% end %>
This works fine until I use Devise and attempt to get to /admins/sign_in. The navbar code is still exactly the same, but I get an UrlGenerationError:
No route matches {:action=>"show", :controller=>"devise/groups", :id=>4, :locale=>nil}
My guess is the error stems from the controller being "devise/groups" as that's the only difference I spot. Is there a way I can tell it to not prepend "devise"? Or do I have to write new routes for all these bits? If I have to add new routes, how can I use resources in routes?
I suspect Devise will also break other links on other pages that I had to code this way.
routes:
Rails.application.routes.draw do
devise_for :admins
get 'search/index'
get 'tags/:tag', to: "search#index", as: :tag
scope "(:locale)", :locale => /#{I18n.available_locales.join("|")}/ do
get 'home/index'
root :to => "home#index"
resources :brands
resources :faqs
resources :categories
resources :subgroups
resources :groups
end
UPDATE: I tried changing the link to the following
<% #groups.each do |group| %>
<li id=<%= group.id %>><%= link_to(t("navbar." + group.name.singularize.downcase), url_for(:controller => 'groups', :action => 'show', :id => group.id)) %></li>
<% end %>
But it still comes up with "devise/groups" as the controller when I access the sign-in page. After I sign in, there's no problem.
I have a strange "fix" but it certainly does not feel correct in the slightest. I created new Controllers that derive from Devise::[name]Controllers, and did the following to whatever methods I needed
def new
super
end
Then edited routes.rb
devise_for :admins, :controllers => {:[name] => "[name]"}
with a new :[name] => "[name]" pair for each Controller I had to make.
determined which ones I needed by looking at rake routes. Everything's working, but I'm sure there's a cleaner fix than this out there.
p.s. you may need to run rails g devise:views

Couldn't find User with id=sign_out

Sign-out link isn't working in my rails application.
I have checked my routes.rb which is listed below and my application.html.erb looks to follow the right path.
Getting the following error.
ActiveRecord::RecordNotFound in UsersController#show
Couldn't find User with id=sign_out
Rails.root: /Users/patrickwalsh/rails_projects/ytutorial
Application Trace | Framework Trace | Full Trace
app/controllers/users_controller.rb:4:in `show'
lib/disable_assets_logger.rb:11:in `call'
My routes.rb
Refectory::Application.routes.draw do
devise_for :users, :controllers => { :registrations => "users" }
devise_scope :user do
get 'login', to: "devise/sessions#new", as: "login"
get 'logout', to: "devise/sessions#destroy", as: "logout"
get 'logout', to: "users/sessions#destroy", as: "logout"
get 'signup', to: "users#new", as: "signup"
match '/users/:id', :to => 'users#show', :as => :user
end
root :to => 'tutorials#index'
devise_for :users do get '/users/sign_out' => 'devise/sessions#destroy'
get 'users/:id' => 'users#show'
end
resources :tutorials
resources :comments, only: [:show, :create, :update, :destroy]
resources :tutorials do
member { post :vote }
end
if Rails.env == "development"
match 'errors/404' => 'errors#error_404'
match 'errors/500' => 'errors#error_500'
end
unless Rails.application.config.consider_all_requests_local
match '*not_found', to: 'errors#error_404'
end
match 'tagged' => 'tutorials#tagged', :as => 'tagged'
end
and my application.html which seems to be following the right route from what I can see.
Any help is greatly appreciated!
<% if current_user.present? %>
<li><%= link_to "Log out", destroy_user_session_path, (:method => "delete") %></li>
<% else %>
<li><%= link_to "Log in", new_user_session_path %></li>
<li><%= link_to "Sign up", new_user_registration_path %></li>
<% end %>
My users controller as well as I have a suspicion this is where the problem lies but not sure what the error is.
class UsersController < Devise::RegistrationsController
def show
#user = User.find(params[:id])
#tutorials = #user.tutorials
end
end
I had the same issue. My routes were in the correct order, the link_to method was properly used, and Rails kept triggering the users/:id route with :id => :sign_out. I figured out that was because I removed jquery_ujs from my application.js file...
jquery_ujs handles the data-method attribute in the links (generated by link_to when you use the method option), which is used to determine the correct route as explained here: https://thoughtbot.com/blog/a-tour-of-rails-jquery-ujs
So just make sure the you have the following included in your application.js:
//= require jquery
//= require jquery_ujs
If you are calling /users/sign_out directly from the URL it won't work because the routes is:
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
id est, it uses the DELETE method. You need to change your devise initializer to:
config.sign_out_via = :get
other option would be to create a small form and its button with DELETE as method.
This worked for me
#form
<%= link_to(destroy_user_session_path, {:class => "nav-link", :method => :delete}) do %>
<span class="sidebar-normal"> Logout </span>
<% end %>
#routes
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end
I have started noticing this error after removing rails-ujs. This was done as part of the upgrade to Rails 7 with ImportMap and Hotwire suite. Changing link_to to button_to has fixed this error in this case.
<%= button_to 'Log out', destroy_user_session_path, method: :delete %>
https://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html#replacements-for-rails-ujs-functionality
None of this solutions worked for me.
Also it happens just in development mode for me...
I fixed it by adding
if params[:id] = "sign_out"
sign_out current_user
return
end
in the set user function. Not the prettiest solution but it works...
You need to move:
devise_for :users do get '/users/sign_out' => 'devise/sessions#destroy'
over your devise_scope. Rails is looking for routes from top of Routes file. Your sign out url matches users/:id, hence it is trying to render show action with sign_out being an id.
UPDATE:
Actually, do you really need the last line in your devise_scope block?
Since non of the other answers worked, I found that you could change the base path for every Devise endpoint as described here. So, what I did was to user devise_for on routes.rb:
devise_for :users,
path: 'devise'
Then, all my Devise routes started with devise instead of users so the conflict was gone.
Sorry to bump this up but the "correct" anwser is not to mess around with routes risking breaking many things.
IF you want a disconnect on a GET then actually configure Devise like so in initializer/devise.rb
# The default HTTP method used to sign out a resource. Default is :delete.
config.sign_out_via = :get
As mentionned in the Devise documentation.
Short answer: use link_to with method DELETE
<%= link_to 'Logout', destroy_user_session_path(current_user), method: :delete %>
explanation:
If you take a look at your Routes you'll see
Helper
destroy_user_session_path
the HTTP verb is
DELETE
the Path
/users/sign_out(.:format)
Controller#Action
devise/sessions#destroy
link_to defaoult method is get, this is "the why" (in a simplistic way of explaning). However, you can specify by using method: :method name
I got this error when using devise in a rails 7 app (with bootstrap):
ActiveRecord::RecordNotFound (Couldn't find User with 'id'=sign_out)
I don't fully understand it myself yet, but basically just open another terminal window, type ./bin/dev and hit enter, and (I guess) it loads your javascripts.

Ruby on Rails - Route to home#index

This one is a two-parter. Initially I had just one controller:
$ rails generate controller home index
...and I made that my root.
Recently, though, I wanted to get the database involved. So I made a scaffold called Daily and switched the root to dailies#index instead of home#index.
That worked just fine. Everything seems to be working fine.
...only problem is that I want to use home#index for something else... but now I have no way to link to it.
This is my routes.rb file:
LiquidAdmin::Application.routes.draw do
resources :dailies
devise_for :users
get '/auth/:provider/callback', to: 'sessions#create'
get "home/bandwall"
get "home/index" :to => "home#index"
# get "dailies/index"
root :to => "dailies#index"
and these are my routes:
home_index GET /home/index(.:format) home#index
I've tried.
<% link_to "Home", home_path %>
<% link_to "Home", home_index %>
<% link_to "Home", home/index %>
Nothing will get me back to that file... even though it was working just fine when it was the root.
Now all of this could've been avoided if "Plan A" had worked...
Plan A was just to make this Daily scaffold and do something like:
<% #dailies.each do |daily| %>
This worked as a link from the Daily index... but not as a link from home#index. Which is why I switched the root. I was getting annoyed and it was easier.
So my questions: 1. How do I link to the old home#index? 2. How should I have queried the dailies tables from home#index?
Assuming you have a Daily model.
routes.rb
resources :dailies
get "home/index"
Running rake routes:
dailies GET /dailies(.:format) dailies#index
POST /dailies(.:format) dailies#create
new_daily GET /dailies/new(.:format) dailies#new
edit_daily GET /dailies/:id/edit(.:format) dailies#edit
daily GET /dailies/:id(.:format) dailies#show
PUT /dailies/:id(.:format) dailies#update
DELETE /dailies/:id(.:format) dailies#destroy
home_index GET /home/index(.:format) home#index
app/controllers/dailies_controller.rb
class DailiesController
def index
#dailies = Daily.all
end
end
app/views/dailies/index.html.erb
<%= link_to "Home", home_index_path %>
<% #dailies.each do |daily| %>
<%= link_to 'A daily', daily_path(daily) %>
<% end %>

link_to "about",about_path showing the error in ROR

i am working in Ruby on rails.. i am new to this..
i have used a line
<%= link_to "about",about_path %>
which throws me a error as,
undefined local variable or method `about_path' for #<ActionView::Base:0xb5f5baa8>
i am having the page about.html under app/views/pages/
please give some suggestions of why i am getting like this .
I just had the same problem using the Hartl's tutorial. Here is what I did.
When asking rake routes, I have :
tomsihap-MBP:sample_app tomsihap$ rake routes
Prefix Verb URI Pattern Controller#Action
root GET / static_pages#home
static_pages_help GET /static_pages/help(.:format) static_pages#help
static_pages_about GET /static_pages/about(.:format) static_pages#about
static_pages_contact GET /static_pages/contact(.:format) static_pages#contact
Then the correct path is :
<%= link_to "About", static_pages_about_path %>
And not <%= link_to "About", about_path %> as suggested by Hartl's guide.
EDIT :
Ok now I understand. That is because routes were defined like that :
Rails.application.routes.draw do
root 'static_pages#home'
get 'static_pages/help'
get 'static_pages/about'
get 'static_pages/contact'
Instead of, later explained into the tutorial :
Rails.application.routes.draw do
root 'static_pages#home'
get 'help' => 'static_pages#help'
get 'about' => 'static_pages#about'
get 'contact' => 'static_pages#contact'
Using this way, the correct path now is :
<%= link_to "About", about_path %>
Your code is looking for what is called a named route. You need to define these in config/routes.rb. In addition you will need some controller and action to handle them. See this post describing a very simple way to handle static pages by way of illustration.
To get the about_path named route, then you would add this to routes.rb
map.about "/pages/about", :controller => "pages", :action => "show", :id => "about"
Then add your about page contents to a file called app/views/pages/about.html.erb
Finally:
$ rake routes
tells you all of the named routes defined for your application and what they do
I guess your about page is "static". Check this..
routes.rb
# rails 2.3.x
map.about "/pages", :controller => 'pages', :action => 'about'
Controllers/pages_controller.rb
class PagesController < ApplicationController
def about # not needed, only for "tidiness"
end
end
... and your erb file have to be here: Views\pages\about.html.erb
Is in your routes.rb something like map.resources :about ?
If you don't know why it should be there or what is that, read about RESTful Routing on guides.

Resources