Mongoid::Errors::DocumentNotFound in UsersController#show - mongodb

I am getting the error Mongoid::Errors::DocumentNotFound in UsersController#show whenever I am trying to click on signout in my app which uses mongoid rails 4.0.1 and devise.
My user controller code is
class UsersController < ApplicationController
before_filter :authenticate_user!
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
end
The error is:
Problem: Document(s) not found for class User with id(s) sign_out. Summary: When calling User.find with an id or array of ids, each parameter must match a document in the database or this error will be raised. The search was for the id(s): sign_out ... (1 total) and the following ids were not found: sign_out. Resolution: Search for an id that is in the database or set the Mongoid.raise_not_found_error configuration option to false, which will cause a nil to be returned instead of raising this error when searching for a single id, or only the matched documents when searching for multiples.
Please help me in this issue.

A similar question, is here.
While all the first answer is important and needs to be checked (make sure you have :method => :delete on your 'Sign Out' link), it is the third answer which fixed it for my Rails 4.1.6 + Mongoid app: adding jquery_ujs.
Specifically, adding //= require jquery_ujs to my application.js file took my broken link and made it sign out sucessfully.

Related

TYPO3 v11.5 #1578950324 RuntimeException - The given page record is invalid. Missing uid. Backendmodul

After upgrading to TYPO3 v11.5, I get this error in my extensions backend module:
1578950324 RuntimeException
The given page record is invalid. Missing uid.
So I digged a little deeper and found out that this has to do with using the f:be.tableList ViewHelper.
In my BE module I use the ViewHelper like this:
<f:be.tableList
tableName="tx_myext_domain_model_mymodel"
storagePid="1"
fieldList="{0: 'column1', 1: 'column_2'}"
sortField="column1"
enableControlPanels="true"
clickTitleMode="edit" />
Since I register my backend module with 'navigationComponentId' => '', (as mentioned in the documentation) I get this error. But the page tree or something else isn't helpful at this point, so I don't want to show them.
(If I show the page tree with 'navigationComponentId' => 'TYPO3/CMS/Backend/PageTree/PageTreeElement', this error disappears)
It turned out that the ViewHelper checks if the user has access rights via checking if the PID is in the mountPoint. I think this is important and not a bug. Fixing that issue could be hard, because how to check the mountPoint permissions if I don't know the PID. (maybe in the ViewHelper: check against the storagePid?)
But if you disable the page tree, there is no PID to check against.
So I also found out, the current PID is fetched while TYPO3\CMS\Core\Utility\GeneralUtility looks for a given id like this:
$value = $_POST[$var] ?? $_GET[$var] ?? null;
I didn't found a way to set the pid in my Extbase Controller, so I did it easily this way in my listAction:
if( TYPO3_MODE == 'BE' ) {
// if is in the BE-module, set PID to prevent customer authentication check error
$_POST['id'] = 1;
}
(In this case, I set the PID to my rootpage.)
If someone has a better solution, don't hesitate to post it to this question.
Have you disabled the page tree for the backend module? If yes - that's the problem! The settings inheritNavigationComponentFromMainModule => false leads to the error.

How to switch from Sqlite to Postgres while installing Warden on Sinatra on Heroku

This is partly a problem-solving question, partly a "I'm trying to understand what's going on" question. I hope that's allowed. Basically, I'm trying to get Warden user authentication to work with Ruby/Sinatra and Postgres on Heroku.
I got a lot of help from this handy (but oldish) tutorial.
From some Rails experience I am a bit familiar with Active Record. The tutorial didn't mention anything about creating a migration for the User class. I went ahead and made my own migration, with my own properties ("name", "email", "password"), only to discover later that, lo and behold, the properties I put in that migration weren't being used by (and in fact were rejected by) the actual model in use. When I examined the object instances in the database, I found that they had only the properties Warden provided for me ("username" and "password").
I'm just trying to understand what happened here. I migrated down my (apparently unnecessary and ignored) Users migration, and nothing happened. I mean that I was able to create User instances and log in using them just as before.
Then it occurred to me that this old Warden tutorial (from 2012) uses something called DataMapper, which does what Active Record would do today. Is that right? They are both "ORMs"? I'm still confused about why Sinatra completely ignored the User migration I did. Maybe it's just using a different database--I did notice wht might be a new db.sqlite database in my main file. Pretty sure the one I created for Active Record was db/madlibs.sqlite3.
Although it works on my local machine, I'm pretty sure it won't work on Heroku, since they don't support sqlite (pretty sure). That then means I'll have to go back to the Warden documentation and figure out how to get it to work with my Postgres database...right? Any pointers on how to get started with that? Since this will be my first project using any authentication library like Warden, it's pretty intimidating.
Here's what I have so far (repo):
app.rb:
require 'sinatra'
require 'sinatra/activerecord'
require 'sinatra/base'
require './config/environment'
require 'bundler'
Bundler.require
require './model'
enable :sessions
class Madlib < ActiveRecord::Base
end
class SinatraWardenExample < Sinatra::Base
register Sinatra::Flash
end
use Warden::Manager do |config|
config.serialize_into_session{|user| user.id }
config.serialize_from_session{|id| User.get(id) }
config.scope_defaults :default,
strategies: [:password],
action: 'auth/unauthenticated'
config.failure_app = self
end
Warden::Manager.before_failure do |env,opts|
env['REQUEST_METHOD'] = 'POST'
end
Warden::Strategies.add(:password) do
def valid?
params['user']['username'] && params['user']['password']
end
def authenticate!
user = User.first(username: params['user']['username'])
if user.nil?
fail!("The username you entered does not exist.")
elsif user.authenticate(params['user']['password'])
success!(user)
else
fail!("Could not log in")
end
end
end
...non authentication routes...
post '/auth/login' do
env['warden'].authenticate!
flash[:success] = env['warden'].message
if session[:return_to].nil?
redirect '/'
else
redirect session[:return_to]
end
end
get '/auth/logout' do
env['warden'].raw_session.inspect
env['warden'].logout
flash[:success] = 'Successfully logged out'
redirect '/'
end
post '/auth/unauthenticated' do
session[:return_to] = env['warden.options'][:attempted_path]
puts env['warden.options'][:attempted_path]
flash[:error] = env['warden'].message || "You must log in"
redirect '/auth/login'
end
get '/protected' do
env['warden'].authenticate!
#current_user = env['warden'].user
erb :protected
end
model.rb (just the User model):
require 'rubygems'
require 'data_mapper'
require 'dm-sqlite-adapter'
require 'bcrypt'
DataMapper.setup(:default, "sqlite://#{Dir.pwd}/db.sqlite")
class User
include DataMapper::Resource
include BCrypt
property :id, Serial, :key => true
property :username, String, :length => 3..50
property :password, BCryptHash
def authenticate(attempted_password)
if self.password == attempted_password
true
else
false
end
end
end
DataMapper.finalize
DataMapper.auto_upgrade!
It seems like this repo might have solved the problems I'm facing now. Should I study that? The Warden documentation itself is pretty forbidding for a relative beginner. For example, it says "Warden must be downstream of some kind of session middleware. It must have a failure application declared, and you should declare which strategies to use by default." I don't understand that. And then it gives some code...which I also don't quite understand. Advice?? (Should I be working with a teacher/mentor, maybe?)

Moped::Errors::OperationFailure when creating an embedded object

I'm using mongoid 3.1.4 altogether with moped 1.5.1, mongodb 2.4.1, and ruby 1.9.3.
I have next models:
class Practice
include Mongoid::Document
embeds_many :distresses
end
class Distress
include Mongoid::Document
embedded_in :practice
end
When I do something like this it seems to be working:
practice = Practice.create
practice.distresses.create
But when I place safe: true in my config file and I do the same, then I get:
Moped::Errors::OperationFailure: The operation: #<Moped::Protocol::Command
#length=82
#request_id=22
#response_to=0
#op_code=2004
#flags=[]
#full_collection_name="collection.$cmd"
#skip=0
#limit=-1
#selector={:getlasterror=>1, :safe=>true}
#fields=nil>
And actually, I got the error when creating the distress in any way. This also throws the exception:
practice = Practice.create
distress = practice.distresses.build
distress.save
When I check with practice.distresses.count I can see that distresses where created successfully in the database, however I get the exception mentioned above.
Ok, after some days I was able to fix this problem.
In my Distress model I had a before_create callback that was trying to update a field on the Practice parent object. Somehow this makes Moped to create a wrong request that makes MongoDB to fail.
I changed before_create callback for after_create and everything is working now.
Hope this helps somebody else.

Rails 4 with CanCan: unknown attribute error after including load_and_authorize_resource

I'm working in Rails 4 and have gotten CanCan to work well with instructions from this issue, except for one use case that I think might be relatively common.
I have a Comment model, which has_many :comments, through: :replies for nested comments. All of this is working well, until I add load_and_authorize_resource to my comments controller. The problem seems to stem from a hidden field sending an optional :parent_comment_id attribute to my create action.
I've permitted this attribute via strong parameters:
def comment_params
params.require(:comment).permit(:content, :parent_comment_id, :post_id, :comment_id, :user_id)
end
So that I can create the association if a :parent_comment_id is included:
if comment_params[:parent_comment_id] != nil
Reply.create({:parent_comment_id => comment_params[:parent_comment_id], :comment_id => #comment.id})
end
But once I add load_and_authorize_resource, I get an unknown attribute error for :parent_comment_id. What am I missing?
Solution came to me in my sleep. Here's what I did to solve the problem:
The only reason comment_params wasn't normally having a problem on create, was because I was excluding the extra :parent_comment_id parameter, like this:
#comment = post.comment.create(comment_params.except(:parent_comment_id))
When CanCan used the comment_params method however, it did no such sanitation. Hence, the problem. It would have been messy to add that sanitation to CanCan on a per-controller basis, so I did what I should have done all along and instead of passing the :parent_comment_id inside :comment, I used hidden_field_tag to pass it outside of :comment and accessed it through plain, old params.
I hope this helps someone else who makes a similar mistake!

How Does the ActiveResource Get Call show find(:first) or find(:last) requests?

I am developing a Sinatra server that can accept calls from ActiveResource, but can"t determine how to identify Get calls specificying :first or :last.
In Rails 3
User.find(:first) => localhost.com/user.xml
User.find(:last) => localhost.com/user.xml
This works exactly as it should according to the examples in the ActiveResource documentation.
It is clear what path they request (the same one), but it is not clear what happens to the :first or :last elements. I can not find them in the request object on the Sinatra server. Does anyone know what happened to those references?
Thanks for your help.
Code from ActiveResource library
def find(*arguments)
scope = arguments.slice!(0)
options = arguments.slice!(0) || {}
case scope
when :all then find_every(options)
when :first then find_every(options).first
when :last then find_every(options).last
when :one then find_one(options)
else find_single(scope, options)
end
end
last and first just methods from Enumerable module