undefined method `index_path' using relation - ruby-on-rails

I get the following error using device and carrierwave gem:
undefined method `user_media_index_path'
.Showing .../user_medias/new.html.erb where line #3 raised:
I have added index on user_id in user_media model
I have successfully implemented file upload for for single model but I don't know how to do it with a seperate module.
new.html
form_for #media, :html =>{:multipart =>true} do |f|
Upload an Image f.file_field :image
f.submit
end
This is the user model generated using the device gem:
user.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me
has_many :user_media, dependent: :destroy
end
its the model to store the user medias like images,etc i;m using this now only for images
but for future to add more types of media i have created this user_media model
user_media.rb
class UserMedia < ActiveRecord::Base
attr_accessible :anudio, :image, :video
belongs_to :user
mount_uploader :image, MediaUploader
end
This is where its get redirected to when asked for create action for uploading the image
user_medias_controller
class UserMediasController < ApplicationController
def new
#media = UserMedia.new
end
def create
#media=current_user.user_media.build(params[:media])
if #media.save
render'index'
else
render'new'
end
end
end
The routing details are:
routes.rb
Projectx::Application.routes.draw do
get "dashboard/index"
resources :dashboard, :UserMedias
get "home/index"
devise_for :users
root :to => 'home#index'
match 'uploder' =>'UserMedias#new'
rake routes output this all after adding resources suggested by #peter
dashboard_index GET /dashboard/index(.:format) dashboard#index
GET /dashboard(.:format) dashboard#index
POST /dashboard(.:format) dashboard#create
new_dashboard GET /dashboard/new(.:format) dashboard#new
edit_dashboard GET /dashboard/:id/edit(.:format) dashboard#edit
dashboard GET /dashboard/:id(.:format) dashboard#show
PUT /dashboard/:id(.:format) dashboard#update
DELETE /dashboard/:id(.:format) dashboard#destroy
user_medias GET /user_medias(.:format) user_medias#index
POST /user_medias(.:format) user_medias#create
new_user_media GET /user_medias/new(.:format) user_medias#new
edit_user_media GET /user_medias/:id/edit(.:format) user_medias#edit
user_media GET /user_medias/:id(.:format) user_medias#show
PUT /user_medias/:id(.:format) user_medias#update
DELETE /user_medias/:id(.:format) user_medias#destroy
home_index GET /home/index(.:format) home#index
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root / home#index
uploder /uploder(.:format) user_medias#new

the error points to a missing route in your routes file. add this to your routes
resources :user_medias

Related

How to use a form to update a join relationship with a nested route in Rails

I am trying to go to a Restful route when adding/updating a join relationship.
I have the following controllers:
home_controller, stores_controller, user_stores_controller (join table)
With my simpleform, I am updating a user's favorite store (updating a join relationship). However, the route takes me the user_controller (which I don't have/didn't think I needed because devise is handling my users). I'm confused on what route to take. What route is more Restful and if my thinking is correct the route to create a user's favorite stores should be through the users_stores_controller with a Post path of user/:user_id/stores. Another possibility is update with a Patch path of /user/:user_id/stores/:id but I was unsure about this because I'm not just updating one store, a user can select multiple stores with the params attribute of store_ids will be passed
Or should I be updating the actually user using a user_controller with a Post path of /user?
What would the simple_form_for look like as well?
Here is my form:
<%= simple_form_for(#user, html: { class: 'form-horizontal' }) do |f| %>
<%= f.association :stores, as: :check_boxes %>
<%= f.button :submit, "Update Favorite Stores", class: "btn btn-primary" %>
<% end %>
Here are my models:
class User < ApplicationRecord
has_many :user_stores
has_many :stores, through: :user_stores
end
class UserStore < ApplicationRecord
belongs_to :user
belongs_to :store
end
class Store < ApplicationRecord
has_many :user_stores
has_many :users, through: :user_stores
end
Here are my routes:
config/routes:
Rails.application.routes.draw do
devise_for :users
root 'home#index'
resources :user do
resources :stores
end
end
Rails Routes
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root GET / home#index
user_stores GET /user/:user_id/stores(.:format) stores#index
POST /user/:user_id/stores(.:format) stores#create
new_user_store GET /user/:user_id/stores/new(.:format) stores#new
edit_user_store GET /user/:user_id/stores/:id/edit(.:format) stores#edit
user_store GET /user/:user_id/stores/:id(.:format) stores#show
PATCH /user/:user_id/stores/:id(.:format) stores#update
PUT /user/:user_id/stores/:id(.:format) stores#update
DELETE /user/:user_id/stores/:id(.:format) stores#destroy
user_index GET /user(.:format) user#index
POST /user(.:format) user#create
new_user GET /user/new(.:format) user#new
edit_user GET /user/:id/edit(.:format) user#edit
user GET /user/:id(.:format) user#show
PATCH /user/:id(.:format) user#update
PUT /user/:id(.:format) user#update
DELETE /user/:id(.:format) user#destroy
Try to specify url in simple form:
<%= simple_form_for(#user, url: user_stores_path, html: { class: 'form-horizontal' }) do |f| %>

Restful Routing for Nested Resource with a Form with Checkbox Options

My models are:
class User < ApplicationRecord
has_many :user_stores
has_many :stores, through: :user_stores
end
class UserStore < ApplicationRecord
belongs_to :user
belongs_to :store
end
class Store < ApplicationRecord
has_many :user_stores
has_many :users, through: :user_stores
end
My routes:
Rails.application.routes.draw do
devise_for :users
root 'home#index'
resources :user do
resources :stores
end
end
rails routes:
Prefix Verb URI Pattern Controller#Action
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root GET / home#index
user_stores GET /user/:user_id/stores(.:format) stores#index
POST /user/:user_id/stores(.:format) stores#create
new_user_store GET /user/:user_id/stores/new(.:format) stores#new
edit_user_store GET /user/:user_id/stores/:id/edit(.:format) stores#edit
user_store GET /user/:user_id/stores/:id(.:format) stores#show
PATCH /user/:user_id/stores/:id(.:format) stores#update
PUT /user/:user_id/stores/:id(.:format) stores#update
DELETE /user/:user_id/stores/:id(.:format) stores#destroy
user_index GET /user(.:format) user#index
POST /user(.:format) user#create
new_user GET /user/new(.:format) user#new
edit_user GET /user/:id/edit(.:format) user#edit
user GET /user/:id(.:format) user#show
PATCH /user/:id(.:format) user#update
PUT /user/:id(.:format) user#update
DELETE /user/:id(.:format) user#destroy
In my join table, I'm going to record User's favorite stores, stores that the user wants to favorite. That will be done by a form with checkboxes, and the stores the user already favorite will be checked.
I have two routes I am confused over. When the user clicks the button to go to the page to see it's favorite stores, should it go to:
1./user/:user_id/stores(.:format)
(If I go to this route, when a form is submitted it should Post to the path /user/:user_id/stores, then in the controller I would take the params store_ids[] and go through each store id, creating it to the database.)
or should it go to
2./user/:id (If I go to this route which my form currently does, I would have to use Patch to the path /user/:id. At this point since I'm using Devise, I would have to create a User's controller, and update the user with store_ids params, along with looping through store_ids to create the join table entry)
I know this may be a multi-part question but whichever route is more appropriate, how would I route the form to reflect this? Currently I have:
<%= simple_form_for(#user, html: { class: 'form-horizontal' }) do |f| %>
<%= f.association :stores, as: :check_boxes, label: false %>
<%= f.button :submit, "Update Favorite Stores", class: "btn btn-primary" %>
<% end %>
But this goes to the User Controller.
The first one is the appropriate. The second one is for users show page.
In your form helper you can just use collection select (I'm not sure if I'm using the right syntax below):
<%= f.collection_select :user, :store_ids, Store.all.order(name: :asc), :id, :name, {}, { multiple: true, class: "form-control" } %>

Why users/passwords/new is redirect to root in Rails4?

I'm now using Devise gem in a Ruby application.
It seems a password method doesn't work because in somehow, devise controller is a bit modified. When I typed /users/password/new, it goes back to a root.
I followed a tutorial but now I'm stuck at this really important method that I have to provide to the people.
The passwords_controller.rb file is located in controllers/users/password_controller.rb.
And the code is
class Users::PasswordsController < Devise::PasswordsController
prepend_before_filter :require_no_authentication
# Render the #edit only if coming from a reset password email link
append_before_filter :assert_reset_token_passed, only: :edit
# GET /resource/password/new
def new
self.resource = resource_class.new
end
# POST /resource/password
def create
self.resource = resource_class.send_reset_password_instructions(resource_params)
yield resource if block_given?
if successfully_sent?(resource)
respond_with({}, location: after_sending_reset_password_instructions_path_for(resource_name))
else
respond_with(resource)
end
end
( which is a typical devise controller content )
My user.rb model goes as follow.
...
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable, :omniauth_providers => [:google_oauth2] #, :confirmable
...
I have view files in this directory.
views/users/passwords/create.html.erb, edit.html.erb, new.html.erb
views/users/sessions/new.html.erb
views/users/registrations/edit.html.erb, create.html.erb
Routes file goes like this
devise_for :users, controllers: { passwords: "users/passwords", sessions: "users/sessions", registrations: "users/registrations", omniauth_callbacks: "users/omniauth_callbacks" }
Whenever I type "http://localhost:3000/users/password/new", it goes back to root.
This is my route file.
new_user_session GET /users/sign_in(.:format) users/sessions#new
user_session POST /users/sign_in(.:format) users/sessions#create
destroy_user_session GET /users/sign_out(.:format) users/sessions#destroy
user_omniauth_authorize GET|POST /users/auth/:provider(.:format) users/omniauth_callbacks#passthru {:provider=>/google_oauth2/}
user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) users/omniauth_callbacks#:action
user_password POST /users/password(.:format) users/passwords#create
new_user_password GET /users/password/new(.:format) users/passwords#new
edit_user_password GET /users/password/edit(.:format) users/passwords#edit
PATCH /users/password(.:format) users/passwords#update
PUT /users/password(.:format) users/passwords#update
cancel_user_registration GET /users/cancel(.:format) users/registrations#cancel
user_registration POST /users(.:format) users/registrations#create
new_user_registration GET /users/sign_up(.:format) users/registrations#new
edit_user_registration GET /users/edit(.:format) users/registrations#edit
PATCH /users(.:format) users/registrations#update
PUT /users(.:format) users/registrations#update
DELETE /users(.:format) users/registrations#destroy
POST|GET /:controller(/:action(/:id))(.:format) :controller#:action
root GET / landings#index
The log I got when I go to localhost:3000/users/password/new goes like this.
Started GET "/users/password/new" for ::1 at 2015-10-06 04:11:58 +0900 Processing by Users::PasswordsController#new as HTML Redirected to localhost:3000 Filter chain halted as :is_login rendered or redirected Completed 302 Found in 2ms (ActiveRecord: 0.0ms) This is a log that I got right after I posted the address
If you guys have any hint, please let me know!!
Best
I fix it by append /users/password/edit?reset_password_token=aaaaaa
maybe it is the devise bug .

rake routes says route exists but error message says otherwise

I'm following along with a Railscast http://railscasts.com/episodes/235-devise-and-omniauth-revised?view=comments about implementing omniauth into devise, specifically adding Twitter signin. When I add the link to sign into Twitter to my app, I'm getting this error visiting the homepage
<li><%= link_to "Sign In With Twitter", user_omniauth_authorize_path(:provider) %></li>
No route matches {:controller=>"omniauth_callbacks", :action=>"passthru", :provider=>:provider}
If I do rake routes (see below), it shows that I have 'user_omniauth_callback' route, but it doesn't specify a request type (GET, POST) etc, which I'm not sure is significant or not.
I searched this error on SO, and one person had a similar problem that resulted from not including the following code in routes.rb, but I have it included.
devise_for :users, path_names: {sign_in: "login", sign_out: "logout"},
controllers: {omniauth_callbacks: "omniauth_callbacks"}
The error arose before getting to the part of the episode where he adds the omniauth controller; I added it just to be sure but I'm still getting the same error:
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
def all
request.env["omniauth.auth"]
end
alias_method :twitter, :all
end
I'm not really sure what else I can look at. In the devise initializer, I set up config for Twitter
config.omniauth :twitter, ENV["TWITTER_KEY"], ENV["TWITTER_SECRET"]
This is my user model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :omniauthable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :image, :provider, :uid
validates_uniqueness_of :name, :email, :case_sensitive => false
end
Can you make any suggestions about what I might do to fix this problem?
Rake Routes
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_omniauth_authorize /users/auth/:provider(.:format) devise/omniauth_callbacks#passthru {:provider=>/twitter/}
user_omniauth_callback /users/auth/:action/callback(.:format) devise/omniauth_callbacks#(?-mix:twitter)
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
The mistake was that I was passing :provider rather than :twitter as an argument in the link.
Incorrect
<%= link_to "Sign In With Twitter", user_omniauth_authorize_path(:provider) %>
Correct:
<%= link_to "Sign In With Twitter", user_omniauth_authorize_path(:twitter) %>

Rails Mongoid form_for Not Using the Correct Verb

I've got an embedded resource inside of a singular resource (/profile/workout) and am having some problems with the form_for helper.
I've defined the following helper, since profile is just based off the current_user (just redirects to the right url):
def workout_path(*args)
profile_workout_path(*args)
end
I've got the following model:
class Workout
include Mongoid::Document
include Mongoid::Timestamps
field :name, type: String
embedded_in :user
embeds_many :movements
accepts_nested_attributes_for :movements
end
controller:
def new
#workout = current_user.workouts.build
#workout.movements.build
end
routes:
ComposerDelete::Application.routes.draw do
authenticated :user do
root :to => 'home#index'
end
root :to => "home#index"
devise_for :users
resources :users do
end
resource :profile do
resources :workouts
end
end
and form
= form_for #workout do |f|
%fieldset
= f.label :name
= f.text_field :name
= f.fields_for :movements do |builder|
= render "movement_fields", f: builder
= link_to_add_fields "Add Movement", f, :movements
= f.submit "Create"
When I visit the url: http://localhost:3500/profile/workouts/50b99b70f0f800cd53000002/edit, the form has the following header:
<form accept-charset="UTF-8" action="/profile/workouts/50b99b70f0f800cd53000002" class="edit_workout" id="edit_workout_50b99b70f0f800cd53000002" method="post">
It gets the right id (edit_<model>_<id>), but the wrong method (post, should be put), also, the submit button says Create instead of Update. The form works correctly, and updates the workout.
rake routes:
root / home#index
root / home#index
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
profile_workouts GET /profile/workouts(.:format) workouts#index
POST /profile/workouts(.:format) workouts#create
new_profile_workout GET /profile/workouts/new(.:format) workouts#new
edit_profile_workout GET /profile/workouts/:id/edit(.:format) workouts#edit
profile_workout GET /profile/workouts/:id(.:format) workouts#show
PUT /profile/workouts/:id(.:format) workouts#update
DELETE /profile/workouts/:id(.:format) workouts#destroy
profile POST /profile(.:format) profiles#create
new_profile GET /profile/new(.:format) profiles#new
edit_profile GET /profile/edit(.:format) profiles#edit
GET /profile(.:format) profiles#show
PUT /profile(.:format) profiles#update
DELETE /profile(.:format) profiles#destroy
The method will always be POST, not PUT - your browser does not support PUT natively, so Rails hacks around this by using a hidden form field inside the form with _method=PUT. See here for some documentation on this.
also, your own code says = f.submit "Create" so it's no wonder the button says 'Create'.

Resources