Nested routes, passing :user_id - ruby-on-rails

I would like to create New Task button which will redirect to /users/:user_id/tasks/new
Routes:
devise_for :users
resources :users do
resources :tasks, shallow: true
end
Task Controller:
def new
#task = Task.new
end
View:
<%= link_to "New Task", new_user_task_path(#user) %>
but it gives me - No route matches {:action=>"new", :controller=>"tasks", :user_id=>nil} missing required keys: [:user_id] error.

Instead of having new_user_task_path(#user) you would like to have probably new_user_task_path(current_user). #user is nil in this case.

Related

No route matches {:controller=>"submissions"}

I get this error when I'm running a test that simply does get :index. Here is the test code:
class SubmissionsControllerTest < ActionController::TestCase
setup do
#submission = submissions(:one)
end
test "should get index" do
get :index
assert_response :redirect
# assert_not_nil assigns(:submissions)
end
I have a route set up for this controller though in my routes.rb file:
resources :courses do
resources :assignments do
get 'export', :controller => 'assignments', :action => 'export'
resources :memberships
resources :submissions do
resources :evaluations do
delete 'destroy', controller: 'reviews', action: 'destroy'
end
end
resources :questions do
resources :responses
resources :scales
end
resources :reviews do
get :assign_reviews, :on => :collection
post :edit_review, :on => :collection
end
end
end
Also, this is what I get for submissions routes when I run rake routes:
course_assignment_submissions GET /courses/:course_id/assignments/:assignment_id/submissions(.:format) submissions#index
POST /courses/:course_id/assignments/:assignment_id/submissions(.:format) submissions#create
new_course_assignment_submission GET /courses/:course_id/assignments/:assignment_id/submissions/new(.:format) submissions#new
edit_course_assignment_submission GET /courses/:course_id/assignments/:assignment_id/submissions/:id/edit(.:format) submissions#edit
course_assignment_submission GET /courses/:course_id/assignments/:assignment_id/submissions/:id(.:format) submissions#show
PUT /courses/:course_id/assignments/:assignment_id/submissions/:id(.:format) submissions#update
DELETE /courses/:course_id/assignments/:assignment_id/submissions/:id(.:format) submissions#destroy
And here is my code for the index action:
def index
if !current_user.instructor?(#course)
raise CanCan::AccessDenied.new("Not authorized!")
end
registrations = #course.registrations
#students = registrations.select{|r| !r.user.pseudo or #assignment.memberships.any?{|m| m.pseudo_user_id == r.user_id } }.map{|r| r.user }
respond_to do |format|
format.html # index.html.erb
format.json { render json: #students }
end
end
Does anyone know where this error could be coming from then?
Because your submissions controller is nested into assignments and assignments into courses you have to pass an :assignment_id and a :course_id into your get request.
So for example:
get :index, course_id: your_course, assignment_id: your_assignment

How to Use Sessions to walk user through Sign Up?

On the home page:
sessions/_goal.html.erb
<%= simple_form_for(:session, url: new_goal_path) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
# ERROR MESSAGE:
Routing Error
No route matches [POST] "/goals/new"
Once the user submit's that he should be redirected to:
sessions/_habit.html.erb
<%= simple_form_for(:session, url: new_habit_path) do |f| %>
<%= f.text_field :name %>
<%= f.submit %>
<% end %>
Once the user submit's that he should be redirected to:
<%= link_to "Sign Up via Facebook", "/auth/facebook" %> or
<%= link_to "Sign Up via Email", signup_path %>
The information they put in those two partials should then be stored so that when they are signed in they will see it as part of their profile.
sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def goal
end
def facebook
user = User.from_omniauth(env["omniauth.auth"])
session[:user_id] = user.id
redirect_to root_url
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
if user.activated?
log_in user
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
redirect_to root_url
else
message = "Account not activated. "
message += "Check your email for the activation link."
flash[:warning] = message
redirect_to root_url
end
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new'
end
end
def destroy
log_out if logged_in?
redirect_to root_url
end
end
routes
Rails.application.routes.draw do
put '/mark_completed/:id', to: 'habits#mark_completed', as: 'mark_completed'
put '/mark_accomplished/:id', to: 'goals#mark_accomplished', as: 'mark_accomplished'
get 'notes/index'
get 'notes/new'
get 'notifications/index'
get 'auth/:provider/callback', to: 'sessions#facebook'
get 'auth/failure', to: redirect('/')
get 'signout', to: 'sessions#destroy', as: 'signout'
get 'password_resets/new'
get 'password_resets/edit'
get "/users/:user_id/goals", to: "goals#user_goals", as: "user_goals"
shallow do
resources :habits do
resources :comments
resources :notes
resources :notifications
end
resources :valuations do
resources :comments
resources :notes
resources :notifications
end
resources :goals do
resources :comments
resources :notes
resources :notifications
end
resources :stats do
resources :comments
resources :notes
resources :notifications
end
end
resources :notes
resources :habits do
collection { post :sort }
resources :notes
resources :notifications
resources :comments do
resources :likes
end
resources :likes
member do
post :like
post :notifications
end
resources :levels do
# we'll use this route to increment and decrement the missed days
resources :days_missed, only: [:create, :destroy]
end
end
resources :goals do
resources :notes
resources :comments
member do
post :like
end
end
resources :valuations do
resources :notes
resources :comments
resources :notifications
member do
post :like
post :notifications
end
end
resources :stats do
resources :notes
resources :comments
resources :notifications
member do
post :like
end
end
resources :results
resources :users
resources :account_activations, only: [:edit]
resources :activities do
resources :valuations
resources :habits
resources :stats
resources :goals
end
resources :notifications do
resources :valuations
resources :habits
resources :stats
resources :goals
resources :comments
end
resources :comments do
resources :comments
resources :notifications
member do
post :like
end
end
resources :password_resets, only: [:new, :create, :edit, :update]
resources :relationships, only: [:create, :destroy]
get 'tags/:tag', to: 'pages#home', as: :tag
resources :users do
member do
get :following, :followers
end
end
get 'about' => 'pages#about'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
delete 'logout' => 'sessions#destroy'
root 'pages#home'
I have no idea what I'm doing here. Any help would greatly be appreciated :]
That will take some work.
First, fix your routes (post them here as you was rightfully asked).
Next, change your partials into action templates (remove underscore _ from their names).
Then in your controller actions use params[...] to retrieve data (e.g. params[:session][:name] for the first step) and save them in session (session[:name] = params[:session][:name]).
At the end of action call redirect_to :another_action (change :another_action to the concrete action you want next – for example in goal method that would be redirect_to :habit_url – and you should add that habit method to your controller).
Then, in your facebook-related methods you will have session[:name] and other stuff available, so you just fetch it from there and push into database (user.update(name: session[:name])).
Reading material:
Action Controller Overview – you need to attentively read this first of all
Active Record Basics – how to save user details to database
Rails Routing from the Outside In – just look through that, paying attention to places which are relevant to your current setup

ActionController::UrlGenerationError: No route matches

I am receiving a no route matches error from the line <%= link_to "Ask User Out", askout_user_message_path(#user), :class => "button" %>.
This used to work before I added a gem but now it stopped working. I tried moving under collection but I get no luck with that as that's where it used to be.
Routes:
resources :users do |user|
resources :messages do
member do
post :new
get 'askout', action: 'askout'
end
end
collection do
get :trashbin
post :empty_trash
end
end
resources :conversations do
member do
post :reply
post :trash
post :untrash
end
end
Old Routes:
resources :users do |user|
resources :messages do
collection do
post 'delete_multiple'
get 'askout', action: 'askout'
get 'reply', action: 'reply'
end
end
end
My routes changed as I added mailboxer gem.
You'd be better doing this:
#config/routes.rb
resources :users do
resources :messages do
member do
post :new
get :askout
end
end
collection do
get :trashbin
post :empty_trash
end
end
This will give you:
users/1/messages/5/askout
What I think you want:
#config/routes.rb
resources :users do
resources :messages do
post :new
collection do
get :askout
end
end
collection do
get :trashbin
post :empty_trash
end
end
This will give you:
users/2/messages/askout
The path helper will be as determined in the rake routes view -- you should look at it to get an idea as to what your route is called (allowing you to write it accordingly)

Vote with Mongoid at Ruby on Rails

I've got a problem with my vote methods for comments. Im a begginer at RoR and waiting for your suggestions.
The error I get is:
ActionController::RoutingError at /posts/51f7d1279fefa5405a000003 No
route matches {:controller=>"comments", :action=>"vote(1)",
:class=>"post__button--edit"}
My code:
comment.rb
class Comment
include Mongoid::Document
field :name, type: String
field :email, type: String
field :body, type: String
field :up_vote, type: Integer, default: "0"
field :down_vote, type: Integer, default: "0"
belongs_to :post
validates_presence_of :name, :email, :body
def self.add_up_vote
self.increment(:up_vote, 1)
end
def self.add_down_vote
self.decrement(:down_vote, 1)
end
end
comment_controller.rb
.
.
.
def vote(a)
#comment = Comment.find(params[:comment_id])
#post = Post.find(params[:post_id])
if a == 1
comment.add_up_vote
redirect_to #post
elsif a == -1
comment.add_down_vote
redirect_to #post
else
redirect_to #post
end
end
routes.rb
Easyblog::Application.routes.draw do
authenticated :user do
root :to => 'home#index'
end
root :to => "home#index"
devise_for :users
resources :users
resources :posts do
resources :comments
member do
post :mark_archived
end
end
end
Im waiting for your help :)
What is a here? I guess it's vote direction
You have to remove argument a from vote action and pass direction via params for link path.
Fox example:
vote_comment_path(#comment.id, dir: 1) # or dir: -1
More than that there is no route for vote action. You can describe it like so:
resources :comments do
put :vote, as: :member
end
upd I would recommend you to read following guide http://guides.rubyonrails.org/routing.html
action in your path is not valid. You link should looks like
= link_to 'Yes', vote_comment_path(comment, dir: 1), method: :put
vote_comment_path can be different you could check it by rake routes command:
$ rake routes
Try changing like this
Easyblog::Application.routes.draw do
resources :posts do
resources :comments do
match :vote
end
member do
post :mark_archived
end
end
end
you could try something like this in youre routes
resources :posts do
resources :comments do
member do
post 'vote'
end
end
member do
post :mark_archived
end
No need to build your own voting system. Take a look at the voteable_mongo gem

Rails 3 routing from root show

Currently
Project101::Application.routes.draw do
match '/:id' => 'companies#show'
resources :companies do
resources :customers
resources :users
resources :categories
resources :addresses
end
devise_for :users
resources :users, :controller => "users"
root :to => "companies#index"
end
Everything belongs to a company. Trying to create routes like www.example.com/:id/customers where :id is always the company id.
At the moment www.example.com/:id works but all url's are generated as /companies/:id/cusotmers.
Saw Rails 3 Routing Resources with Variable Namespace.
Is this the right way of doing this?
EDIT
Kept :as => :company to help generate the URL's, Links, etc a little easier for me. Sure others could do cleaner or better method. Also had to manually create the edit, destroy, new with different urls so I could use them in links if user was admin.
Project101::Application.routes.draw do
match '/' => 'companies#index'
match '/companies' => 'companies#index'
match '/:company_id' => 'companies#show', :as => :show_company
match '/companies/:id/edit' => 'companies#edit', :as => :edit_company
match '/companies/:id/new' => 'companies#new', :as => :new_company
match '/companies/:id/destroy' => 'companies#destroy', :as => :delete_company
scope '/:company_id', :as => :company do
resources :customers
resources :users
resources :categories
resources :services
resources :addresses
end
devise_for :users
resources :users, :controller => "users"
root :to => "companies#index"
end
Then just used basic nested_resources for links, controllers and forms.
class ApplicationController < ActionController::Base
protect_from_forgery
helper_method :current_company
def current_company
if params[:company_id] != nil
#current_company ||= Company.find(params[:company_id])
else
#current_company = nil
end
return #current_company
end
end
Basic links
<%= link_to "Customers", company_customers_path(current_company) %>
links for specific customer
<%= link_to #customer.name, edit_company_customer_path(current_company, #customer) %>
Controllers look like
class CustomersController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
def new
#company = current_company
#customer = #company.customers.new
end
def create
#customer = Customer.new(params[:customer])
if #customer.save
flash[:notice] = "Successfully created customer."
redirect_to company_customer_path(current_company, #customer)
else
render :action => 'new'
end
end
end
And finally my forms look like
<%= form_for [#company, #customer] do |f| %>
<%= f.error_messages %>
....
<% end %>
Yes, if you always want the routes to begin with the company id you can wrap them in a scope like this:
scope ":company_id" do
resources :customers
resources :users
resources :categories
resources :addresses
end

Resources