I'm currently experiencing an issue with the latest version of CanCan. It seems that the gem won't load singleton resources with pluralized names.
class Preferences < ActiveRecord::Base
self.table_name = 'preferences'
belongs_to :user
end
class User < ActiveRecord::Base
has_one :preferences
end
#controller
class PreferencesController < ApplicationController
before_filter :authenticate_user! #from Devise
load_and_authorize_resource :singleton => true,
:through => :current_user,
:through_association => :preferences,
:parent => false
end
#ability.rb
class Ability
include CanCan::Ability
def initialize(user)
can [:read, :update], Preferences, :user_id => user.id
end
end
I keep getting an error like this when I run my controller spec:
Failures:
1) PreferencesController GET #show should return http success
Failure/Error: get :show
NameError:
uninitialized constant Preference
# ./spec/controllers/preferences_controller_spec.rb:10:in `block (3 levels) in <top (required)>'
It seems no matter what combination of load_resource arguments I try, I can't get my specs to pass again without reverting back to loading the resource manually like this:
class PreferencesController < ApplicationController
before_filter :authenticate_user!
def show
#preferences = current_user.preferences
authorize! :read, #preferences
end
end
Is there some magic combination of load_and_authorize_resource parameters I need to use? I have this same configuration working in another singleton controller where the resource falls under normal Rails conventions (i.e. User has_one :profile), so I know this works already under normal situations.
Related
I am using rails 5 and I am trying to save an object to my db with some parameters on a get request. But for some reason my object is getting saved twice.
here is my code in controller
class ParticipantCardController < ApplicationController
before_action :authenticate_user!
before_action :authenticate_current_user_profile
def participate
# byebug
params.permit(:event_id, :_method, :authenticity_token)
event_id=params[:event_id].to_i
byebug
#new_participant = ParticipantCard.new
#new_participant.user=current_user
#new_participant.event_id=event_id
#new_participant.name=" "
#new_participant.description=" "
#new_participant.save
# end
# flash[:error] = #new_participant.errors.messages
end
this is code calls the insert sql query twice, like so:
terminal query
RubyMine7.0.1 shows this alert in every controller class.
A controller class file below.
Thanks.
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
helper_method :current_user, :logged_in?
before_action :authenticate
private
def current_user
return unless sessions[:user_id]
#current_user ||= User.find(session[:user_id])
end
def logged_in?
!!session[:user_id]
end
def authenticate
return if logged_in?
redirect_to root_path, alert: 'ログインして下さい。'
end
end
I got the very same error when I imported a project from existing sources and the Project SDK was not set properly for the project.
There are three models in my app: User, Subject and Note.
I've already embedded Note model into Subject model and it works. Now when I try to embed Subject into User always get Mongoid::Errors::InvalidFind coming from this line of code:
In the method one should define to use in before_action at the beginning of the controller
#user = User.find(params[:user_id])
subjects_controller
class SubjectsController < ApplicationController
#before_filter :authenticate_user!, only: [:index]
before_action :set_subject, only: [:show, :edit, :update, :destroy]
before_action :load_user
def index
#subjects = #user.subjects
end
def new
#subject = #user.subjects.build
end
def show
end
def create
#subject = #user.subjects.create(subject_params)
respond_to do |format|
if #subject.save
format.html {redirect_to subject_path(#subject)}
else
format.html {render 'new'}
end
end
end
def update
if #subject.update(subject_params)
redirect_to #subject
else
render 'edit'
end
end
def delete
end
private
def subject_params
params.require(:subject).permit(:name)
end
def set_subject
#subject = #user.subject.find(params[:id])
end
def load_user
#user = User.find(params[:user_id])
end
end
Routes
resources :users do
resources :subjects do
resources :notes
end
end
Right now I'm pretty stuck here because haven't found a way to work this around, hope someone around can give a hand.
Take into account this RoR best practice "Resources should never be nested more than 1 level deep." http://guides.rubyonrails.org/routing.html#nested-resources
A collection may need to be scoped by its parent, but a specific member can always be accessed directly by an id, and shouldn’t need scoping (unless the id is not unique, for some reason).
http://weblog.jamisbuck.org/2007/2/5/nesting-resources
app/helpers/sessions_helper.rb
module SessionsHelper
def sign_in(user)
cookies.permanent[:remember_token] = user.remember_token
self.current_user = user
end
def sign_out
self.current_user = nil
cookies.delete(:remember_token)
end
def signed_in?
!current_user.nil?
end
def current_user=(user)
#current_user = user
end
def current_user
#current_user ||= User.find_by_remember_token(cookies[:remember_token])
end
end
Tests defined in section 9.2.1 Requiring signed-in users are failing:-
At first I was getting sign_in method not found then I added
include SessionsHelper
in spec/utilities.rb file after that I started getting below error, saying no method with name permanent exists in Rake::Test::CookieJar.
Is it due to some Gem version issue.
1) User Pages edit page
Failure/Error: before { sign_in user}
NoMethodError:
undefined method `permanent' for #<Rack::Test::CookieJar:0x007ff12c661e88>
# ./app/helpers/sessions_helper.rb:3:in `sign_in'
# ./spec/requests/user_pages_spec.rb:55:in `block (3 levels) in <top (required)>'
Just ran into the same problem and got it fixed.
It seems they are not referring to the sign_in method in sessions_helper.rb but the the sign_in method in spec/support/utilities.rb
In my case this helper method in utilities.rb had a different name, after renaming it everything worked fine :-)
So I have a rails app 2.x app that works fine via the web, but when trying to perform a POST I keep getting "Redirected to http://localhost:3000/session/new Filter chain halted as [:require_user] rendered_or_redirected.". In my iPhone app, I can create a new session and sign-in via my iPhone app, but cannot POST to say the POSTS_Controller.
I have this in my code
Posts_Controller
before_filter :require_user, :only => [:create, :update, :destroy]
Application_Controller
# Filters added to this controller apply to all controllers in the application.
# Likewise, all the methods added will be available for all controllers.
class ApplicationController < ActionController::Base
include AuthenticatedSystem
include Geokit::Geocoders
helper :all # include all helpers, all the time
#session :session_key => '_cwa_session_id'
#filter_parameter_logging :password
# See ActionController::RequestForgeryProtection for details
# Uncomment the :secret if you're not using the cookie session store
protect_from_forgery # :secret => 'eejj7eded74769099999944a729b4f'
#filter_parameter_logging(:password)
before_filter :login_from_cookie
before_filter :find_user_interests
before_filter :find_user_posts
protected
def find_user_interests
#user_interests = cur_user ? cur_user.interesting_posts : []
logger.debug "User interests hash: #{current_user.inspect}"
end
def find_user_posts
#user_posts = cur_user ? cur_user.posts : []
end
def cur_user
User.find(session[:user_id]) if session[:user_id]
end
def require_user
unless cur_user
flash[:error] = "You must be logged in to do that."
redirect_to '/session/new'
return false
end
end
geocode_ip_address
def geokit
#location = session[:geo_location]
end
end
I have been working on this for 2 months and cannot figure out the issue. In my iPhone app I am using ObjectiveResource. I am sending over json and have "Mime::Type.register_alias "application/json", :json" set up on the rails side.
I am not a rails developer, but the before filter for require_user is unable to pass the cur_user test in that is cannot find :user_id in the session hash. Are you sure that you have a session that persists when using the iPhone? Are you using devise for authentication? Just for kicks, does it work if you manually pass the user_id as params?