I am busy going through PBP - Agile Web Development with Rails and implementing the locale switcher.
However when I try switch between english and spanish I get a error:
No route matches [POST] "/en"
My controller is as follows:
class StoreController < ApplicationController
skip_before_filter :authorize
def index
if params[:set_locale]
redirect_to store_path(locale: params[:set_locale])
else
#products = Product.order(:title)
#cart = current_cart
end
end
end
and an extract of the application.hmtl.erb that is being used;
<div id="banner">
<%= form_tag store_path, class: 'locale' do %>
<%= select_tag 'set_locale', options_for_select(LANGUAGES, I18n.locale.to_s), onchange: 'this.form.submit()' %>
<%= submit_tag 'submit' %>
<%= javascript_tag "$('.locale input').hide()" %>
<% end %>
<%= image_tag("logo.png") %>
<%= #page_title || t('.title') %>
</div>
the routing folder is as follows:
scope'(:locale)' do
resources :users
resources :orders
resources :line_items
resources :carts
resources :products do
get :who_bought, on: :member
end
root to: 'store#index', as: 'store'
end
Cant figure out what I did wrong. If I enter /en or /es in the url it works correctly. However choosing it in the drop down that is created I get the error mentioned
Found the issue, the form_tag was expecting a POST so I changed
<%= form_tag store_path, class: 'locale' do %>
to
<%= form_tag store_path, class: 'locale', :method => :get do %>
and it worked
You are missing an slash in the scope as guides states:
# config/routes.rb
scope "/:locale" do
resources :books
end
http://guides.rubyonrails.org/i18n.html#setting-the-locale-from-the-url-params
Related
So I'm getting the error stated in the title. What code would I have to write in my Postscontroller to fix this? I'm not sure what I would have to do here, would I have to define rsvp in my post controller? If thats the case how would I go about doing that?
class RsvpController < ApplicationController
def create
rsvp = current_user.rsvps.build({post_id: params[:id]})
if rsvp.save
end
end
end
Show.html.erb
<p>
<strong>Date:</strong>
<%= #post.date %>
</p>
<p>where:<%=#post.longitude %>, <%=#post.latitude%></p>
<p>
<strong>Name:</strong>
<%= #post.name %>
</p>
<p>
<strong>User_id:</strong>
<%= #post.user_id %>
</p>
<p>
<strong>Description:</strong>
<%= #post.description %>
</p>
<% if current_user == #post.user %>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%end%>
<%= link_to 'Back', posts_path %>
<%= button_to "Rsvp now", rsvp_post_path(#post), class: "btn btn-primary" %>
routes.rb
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
resources :posts
devise_for :users
root 'home#index'
get 'home/ruby_meetup'
resources :posts do
post 'rsvp', on: :member
end
Also I want it so it shows the list of people who already rsvped for the event. How would I go about doing that? I would appreciate some help as I'm still learning rails and this is my first project.
By the following line, you define the route:
resources :posts do
post 'rsvp', on: :member
end
By this line you're requesting this route:
To process the request, you need a controller action rsvp, which actually the error states.
Thus, just define the action (method) and process the request:
class RsvpController < ApplicationController
def create
rsvp = current_user.rsvps.build({post_id: params[:id]})
if rsvp.save
end
end
def rsvp
# process the request here...
end
end
All of the sudden I am getting this error even though it has been working for a while:
No route matches [POST] “/stories/id/invites”
Routes:
story_invites_path GET /stories/:story_id/invites(.:format) invites#index
routes.rb
resources :stories do
match '/stories/:id/invite', to: 'invite#show', via: 'get'
resources :invites , only: [:index, :show, :destroy ]
end
invites/index view
<%= form_for #invite , :url => story_invites_path do |f2| %>
<%= f2.text_field :user_id, :value => user.id , :class => 'number_field' %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
invites controller
def create
#invite = #story.invites.new(invite_params)
if #invite.save
flash[:success] = 'The user was invited!'
redirect_to(:back)
else
render :new
end
end
How do I add a post method to my invites path?
You have all sort of icky things...
This:
resources :stories do
match '/stories/:id/invite', to: 'invite#show', via: 'get'
resources :invites , only: [:index, :show, :destroy ]
end
Should be:
resources :stories do
resources :invites
end
Which will give you:
story_invites GET /stories/:story_id/invites(.:format) invites#index
POST /stories/:story_id/invites(.:format) invites#create
new_story_invite GET /stories/:story_id/invites/new(.:format) invites#new
edit_story_invite GET /stories/:story_id/invites/:id/edit(.:format) invites#edit
story_invite GET /stories/:story_id/invites/:id(.:format) invites#show
PATCH /stories/:story_id/invites/:id(.:format) invites#update
PUT /stories/:story_id/invites/:id(.:format) invites#update
DELETE /stories/:story_id/invites/:id(.:format) invites#destroy
stories GET /stories(.:format) stories#index
POST /stories(.:format) stories#create
new_story GET /stories/new(.:format) stories#new
edit_story GET /stories/:id/edit(.:format) stories#edit
story GET /stories/:id(.:format) stories#show
PATCH /stories/:id(.:format) stories#update
PUT /stories/:id(.:format) stories#update
DELETE /stories/:id(.:format) stories#destroy
If you really want to limit your invite routes, fine. But right now, you're limiting out create. Which is really why you're getting:
No route matches [POST] “/stories/id/invites”
Because you TOLD rails you didn't want a create path. Rails is dumb that way. Does what you tell it. Not what you mean.
Also, this:
match '/stories/:id/invite', to: 'invite#show', via: 'get'
Is just really full of badness and banana slugs. Please don't do that. To yourself. Or to us.
This:
<%= form_for #invite , :url => story_invites_path do |f2| %>
<%= f2.text_field :user_id, :value => user.id , :class => 'number_field' %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
probably needs to look more like this:
<%= form_for :invite, story_invites_path(story) do |f2| %>
<%= f2.hidden_field :invite, :user_id, value: #user.id %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
Use :invite instead of #invite because you're in index and you probably don't have an #invite. If you do, fine. But rails can use the symbol to infer the correct fields.
You're going to have to look up that hidden_field method, because I'm doing this from memory.
And I don't know where you're going to get story from because you're in your index method. But, you can do something like #stories = Story.all. In which case this whole block will need to wrapped in something like:
<% #stories.each do |story| %>
<%= story.name %>
<%= form_for :invite, story_invites_path(story) do |f2| %>
<%= f2.hidden_field :invite, :user_id, value: #user.id %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
<% end %>
Man, this makes me remember why I dislike erb. If you were doing this in HAML, it would be pretty, like unicorns and rainbows:
- #stories.each do |story|
.story-container{id: "story-id-#{story.id}"}
.story-name
= story.name
.story-invite-container
= form_for :invite, story_invites_path(story) do |f2|
= f2.hidden_field :invite, :user_id, value: #user.id
= f2.submit 'Send', class: 'btn btn-primary'
Don't you like unicorns and rainbows? Look at all those beautiful divs with ids and classes just waiting to be dressed up with your butt-kicking, mad-ninja-skills CSS (display: inline-block, anyone?). (Please tell me you're using SASS. Please?)
Now, on submit, your params are going to look something like (I'm making up the story_id and 'user_id` values):
{..., story_id: 4, invite: {user_id: 1}, ...}
I assume in invites_controller, you have something like:
class InvitesController < ActionController::Base
def index
...
#stories = Story.all
...
end
def create
#story = Story.find_by(id: params[:story_id])
#invite = #story.invites.new(invite_params)
if #invite.save
flash[:success] = 'The user was invited!'
redirect_to(:back)
else
render :new
end
end
def invite_params
params.require(:invite).permit(:user_id)
end
end
And that all ought to hang together.
For the life of me, I don't know why you redirect_to :new, but hey whatever floats your boat. (Are sure you don't want to redirect_to stories_path or maybe redirect_to story_path?)
Update your routes.rb to include create in your resources :invites, like this:
resources :stories do
match '/stories/:id/invite', to: 'invite#show', via: 'get'
resources :invites , only: [:index, :show, :destroy, :create ]
end
That change will generate this new route:
story_invites POST /stories/:story_id/invites(.:format) invites#create
I am new bee in rails and trying to figure out how to pass id using custom controller but it look a blocker to me.
below is code of controller :
class UploadsController < ApplicationController
def index
#upload = Upload.new
#uploadimage = Upload.all
end
def home
end
def destroy
end
end
below is the index.html.erb file
<h1>Upload#index</h1>
<p>Find me in app/views/upload/index.html.erb</p>
<%= form_for(#upload, url: "/uploads/home", :html => {:class => 'dropzone'} ) do |f| %>
<div class="fallback">
<input name="file" type="file" multiple />
</div>
<% end %>
<h3>Uploaded images</h3>
<% #uploadimage.each do |image| %>
<% if !image.nil? %>
<%= image_tag("/images/#{image.name}",style: 'height:100px; width:100px;') %>
<%= link_to "delete #{image.name}", uploads_url(image) %>
<% else %>
<p>No images are present in db</p>
<% end %>
<% end %>
below is routes.rb
Rails.application.routes.draw do
get "uploads", to: "uploads#index", via: :get
get "uploads/:id", to: "uploads#destroy", via: :get
get "uploads/index/:id", to: "uploads#destroy", via: :get
get "uploads/index/", to: "uploads#index", via: :get
root "uploads#index"
end
how to pass id to destroy/home action as i m getting id as dot instead of slash
Why you are using custom routes, if rails providing RESTful routes using resources
Rails.application.routes.draw do
resources :uploads
root "uploads#index"
end
Edited:
Rails.application.routes.draw do
resources :uploads, :controller => "custom_controller"
root "uploads#index"
end
This will manage all 7 action, and check rake routes for path for this all 7 action.
I'm trying to add edit functionality to my web app, and am having some trouble. The error page I get back when I try to complete an edit of my Request object indicates that it couldn't find the right route, but the same error page contains a list of routes which includes the route it's looking for. So I'm a bit flummoxed.
The "new" method is almost identical to this edit method and the pages are almost identical as well.
The error page begins No route matches [POST] "/requests/19/edit" and then, partway down the route listing, I see this:
requests_path GET /requests(.:format) requests#index
POST /requests(.:format) requests#create
new_request_path GET /requests/new(.:format) requests#new
edit_request_path GET /requests/:id/edit(.:format) requests#edit
request_path GET /requests/:id(.:format) requests#show
PATCH /requests/:id(.:format) requests#update
PUT /requests/:id(.:format) requests#update
DELETE /requests/:id(.:format) requests#destroy
So Rails seems to be generating a request_path which expects a PATCH, not a POST, right?
routes.rb
Rails.application.routes.draw do
root "pages#index"
resources :destinations
resources :users
resources :manifests
resources :requests
:
request.rb
class Request < ActiveRecord::Base
validates_presence_of :justification
validates_presence_of :required_by
belongs_to :user
belongs_to :manifest
belongs_to :network
has_many :uploaded_files
scope :sorted, lambda{ order("required_by") }
end
edit.html.rb
<% #page_title = "Update Request" %>
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="requests edit">
<h2>Update Request</h2>
<%= form_for :request, url: request_path(#request) do |f| %>
<%= render(:partial => "form", :locals => {:f => f}) %>
<div class="form-buttons">
<%= submit_tag("Update Request") %>
</div>
<% end %>
</div>
requests_controller.rb
def update
#request = Request.find(params[:id])
p = {'file' => params[:request][:uploaded_file], 'request_id' => #request.id}
uf = UploadedFile.create(p)
if #request.update_attributes(request_params)
flash[:notice] = "Request updatred succesfully"
redirect_to :action => 'show', :id => #request.id
else
render 'edit'
end
end
What have I missed?
Change
<%= form_for :request, url: request_path(#request) do |f| %>
to
<%= form_for :request, url: request_path(#request), method: :patch do |f| %>
in your edit.html.erb
form_for(as you are using it) sets POST as default HTTP verb. You need to alter it by setting method :patch which responds to the update action.
You can simplify it to just
<%= form_for #request do |f| %>
Check the APIdoc for more Info.
I have a controller games and a method:
def index
#games = Game.all
end
def set_game
#current_game = Game.find(params[:set_game])
end
In my view I have:
<%= form_tag("/games") do %>
<% #games.each do |g| %>
<%= radio_button_tag(:game_id, g.id) %>
<%= label_tag(:game_name, g.name) %><br>
<% end %>
<%= submit_tag "Confirm" %>
<% end %>
Routes:
resources :games
match 'games', :to => 'game#index'
How can I make this form work for my set_game method?
Thanks.
<%= form_tag(set_game_games_path) do %>
...
<% end %>
#routes.rb
resources :games do
collection do
get '/set_game', :as => :set_game
end
end
That's an example of a custom route:
match "customroute" => "controller#action", :as => "customroutename"
This can be then accessed with "customroutename_url" in your views. If you want to create a custom route for your set_game action, for example, it would be
match "setgame" => "games#set_game", :as => "setgame"
Then you can do
<%= form_tag setgame_url %>
...
<% end %>
You can read more about custom routes here: http://guides.rubyonrails.org/routing.html#non-resourceful-routes