I keep getting, "NoMethodError (undefined method `moments' for nil:NilClass):" - ruby-on-rails

I'm just start to learn ruby and I'm writing a simple API, but I've got an error NoMethodError (undefined method moments' for nil:NilClass): app/controllers/api/v1/moments_controller.rb:8:inindex' Here is a code:
Rails.application.routes.draw do
resources :posts
devise_for :users
namespace :api do
namespace :v1 do
devise_scope :user do
post 'registrations' => 'registrations#create', :as => 'register'
post 'sessions' => 'sessions#create', :as => 'login'
delete 'sessions' => 'sessions#destroy', :as => 'logout'
end
get 'moments' => 'moments#index', :as => 'moments'
post 'moments' => 'moments#create'
end
end
devise_scope :user do
get '/users/sign_out' => 'devise/sessions#destroy'
end
end`
here code : moments_controller.rb
class Api::V1::MomentsController < ApplicationController
skip_before_filter :verify_authenticity_token,
:if => Proc.new { |c| c.request.format == 'application/json' }
before_filter :authenticate_user!
def index
#moments = current_user.moments
end
def create
#moment = current_user.moments.build(params[:moment])
if #moment.save
#moment
else
render :status => :unprocessable_entity,
:json => { :success => false,
:info => #moment.errors,
:data => {} }
end
end
#private
# def moment_params
# params.require(:moment).permit(:title, :completed)
# end
end
Can anyone see what is wrong with my code?

Related

Class level method "undefined"

With the code below:
class TestController < ApplicationController
wrap_parameters :test, format: [:json, :xml], include: self.test_method
def self.test_method
[ :one, :two, :three ]
end
end
I get a RoutingError:
ActionController::RoutingError (undefined method 'test_method' for TestController:Class)
I tried a number of different derivations of this, but nothing is working.
EDIT: routes.rb -- was routing to api.servername/create during error:
TestApp::Application.routes.draw do
resources :subscriptions
# API subdomain
constraints subdomain: 'api' do
get '/' => 'test#index'
post '/create', to: 'test#create'
get '/status', to: 'test#show'
end
# root route
root to: 'pages#index'
# User routes
devise_scope :user do
get 'login' => 'devise/sessions#new', :as => :new_user_session
post 'login' => 'devise/sessions#create', :as => :user_session
delete 'logout' => 'devise/sessions#destroy', :as => :destroy_user_session
get 'register' => 'devise/registrations#new', :as => :new_user_registration
get 'profile' => 'devise/registrations#edit', :as => :edit_user_registration
get 'users' => 'users/registrations#index'
end
devise_for :users, :skip => [:sessions], controllers: { registrations: 'users/registrations' }
end

How to add custom URLs

How to add custom URLs like localhost:3000/one_hour/page/2 instead of localhost:3000/one_hour?page=2
to get '/one_hour', to: 'feed_entries#one_hour'
I use Rails 4, Kaminari and mongoid
routes.rb
Rails.application.routes.draw do
concern :paginatable do
get '(page/:page)', :action => :index, :on => :collection, :as => ''
end
resources :feed_entries, path: 'news', :concerns => :paginatable
get '/one_hour', to: 'feed_entries#one_hour'
end
feed_entries_controller.rb
class FeedEntriesController < ApplicationController
one_hour
#feed_entries = FeedEntry.includes(:source).one_hour.page(params[:page])
end
end
I found a solution:
in routes.rb
get 'one_hour/(page/:page)', controller: 'feed_entries', action: 'one_hour', to: 'feed_entries#one_hour', as: :one_hour

Update the route to just show resource/new as compared to user/user_id/resource/new

I am using rails 4 along with devise my routes.rb reads :
devise_for :users, :path => '',
:path_names => {:sign_in => 'login', :sign_out => 'logout', :sign_up => 'register'},
controllers: { registrations: "registrations", omniauth_callbacks: 'omniauth_callbacks' } do
get "/login" => "devise/sessions#new"
get "/signup" => "devise/registrations#new"
get "/logout" => "devise/sessions#destroy"
get "/login" => "devise/sessions#new"
end
resources :users, :only => [:show, :index], :path => "bloggers" do
resources :posts, :path => "articles"
end
Now when I create a new post as the currently signed in user (lets say the id is 1). The URL on the Post -> New action reads - > https://localhost:3000/bloggers/1/articles/new but I want to show
https://localhost:3000/articles/new, as the new action on the post should always be associated to the current_user.
I would imagine this being possible, but no clue how to do it.
Also a user has_many posts.
Help, please?
Authentication
Very simple actually:
#config/routes.rb
# If you have overridden "path_names", you don't need other paths for Devise
devise_for :users, :path => '',
:path_names => {:sign_in => 'login', :sign_out => 'logout', :sign_up => 'register'},
controllers: { registrations: "registrations", omniauth_callbacks: 'omniauth_callbacks' }
resources :posts, as: "articles", path: "articles"
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_action :authenticate_user!, except: :index
def index
#Stuff here
end
end
The bottom line here is that whenever you want to use an authenticated area (especially with Devise), you just need to "protect" the controller#actions which you want to limit access to. The beauty is that you can use the authenticate_user! helper method to make these work
Further to that, you will then be able to just call current_user in your controller (not having to set the user, as you're doing now):
#app/controllers/posts_controller.rb
class PostsController < ApplicationController
def new
#post = current_user.posts.new
end
def create
#post = current_user.posts.new post_params
#post.save
end
private
def post_params
params.require(:post).permit(:x, :y, :z)
end
end

Devise's registration_path, how it's generated?

Default Devise user signup form looks like this:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
When I run rake routes I don't see any registration prefix, there is user_registration, new_user_registration etc. but not just registration, so how does it work? Where can I find it's source code?
The registration_path route is generated in
Devise::Controllers::UrlHelpers.
As you can see in the code below it just calls your regular routes.
def self.generate_helpers!(routes=nil)
routes ||= begin
mappings = Devise.mappings.values.map(&:used_helpers).flatten.uniq
Devise::URL_HELPERS.slice(*mappings)
end
routes.each do |module_name, actions|
[:path, :url].each do |path_or_url|
actions.each do |action|
action = action ? "#{action}_" : ""
method = "#{action}#{module_name}_#{path_or_url}"
class_eval <<-URL_HELPERS, __FILE__, __LINE__ + 1
def #{method}(resource_or_scope, *args)
scope = Devise::Mapping.find_scope!(resource_or_scope)
_devise_route_context.send("#{action}\#{scope}_#{module_name}_#{path_or_url}", *args)
end
URL_HELPERS
end
end
end
end
generate_helpers!(Devise::URL_HELPERS)
With Devise::URL_HELPERS being:
{:session=>[nil, :new, :destroy], :omniauth_callback=>[], :password=>[nil, :new, :edit], :registration=>[nil, :new, :edit, :cancel], :confirmation=>[nil, :new], :unlock=>[nil, :new]}
Put the following in your routes.rb
devise_for :users, :controllers => {:sessions => 'devise/sessions', :registrations => 'devise/registrations',
:passwords => 'devise/passwords'}, :skip => [:sessions] do
get '/login' => 'devise/sessions#new', :as => :new_user_session
post '/login' => 'devise/sessions#create', :as => :user_session
get '/logout' => 'devise/sessions#destroy', :as => :destroy_user_session
end
And then run rake routes. You can find the devise controller at: List of Devise Controllers

Devise routing error: "Unknown action -- The action 'create' could not be found for UsersController"

My devise set up was working fine before, but now, for some reason, whenever I try to sign up a new user, it tries to call users#create instead of registrations#create. I think it must be a problem with my routes.rb file. I recently added a new resource, "preferences", to my application, so the routing might be wonky:
Indexer2::Application.routes.draw do
resources :preferences
get "home/index"
resources :posts
resources :users
devise_for :users, :controllers => {:registrations => 'registrations', :invitations => 'invitations'}, :except => [:show] do
get "/signup" => "devise/registrations#new", :as => 'user_signup'
get '/logout' => 'devise/sessions#destroy', :as => 'user_logout'
get '/login' => "devise/sessions#new", :as => 'user_login'
end
match '/welcome' => 'pages#welcome'
resources :preferences, :except => [:destory, :edit, :create, :new, :index, :show] do
collection do
post "make_feed_preference"
post "change_preference"
end
end
root :to => "home#index"
end
Your UsersController should have create method.
If you don't want to write your own registration logic just do inheritance from Devise::RegistrationsController < DeviseController:
controller UsersController < Devise::RegistrationsController
#....
end
This will include default Devise methods.

Resources