Admin panel rails 3 - ruby

I want to make an admin controller, it has following 3 views index, members(list of users) and commet(all the feedback from the user) for the following i made following actions in controllers
class AdminController < ApplicationController
before_filter :authenticate_user!
def index
#members = User.all
#comment = Feedback.all
end
def member
#members = User.all
end
def comment
#comment = Feedback.all
end
end
Now I want to make comment and member view such that the admin can delete or edit the feedback or user, now how should write the methods for that?, since all this is happening in the same page?
I did not know what to search for this problem. So I am posting it, it might be repeated

Related

CanCanCan alias method for a controller

In my application I have permissions set up like so for an admin:
can :read, Journey
can :destroy, Journey
can :update, Journey
And I have controllers like so:
class JourneyController < ApplicationController
authorize_resource class: :journey
def index; end
def show; end
end
module Journeys
class VoidJourneyController < ApplicationController
authorize_resource class: :journey
def show; end
def destroy; end
end
end
This is based on how DHH does his controllers: http://jeromedalbert.com/how-dhh-organizes-his-rails-controllers/
Now the issue I have is that because I have a show method inside the VoidJourney controller (this is to show the user some additional information as we talk to an API) it means a user who doesn't have permission to destroy a journey can access it because show is aliased to read and only the destroy is protected in that controller.
CanCanCan has the alias_action method, but that only allows aliasing a method to another for all controllers, not just one.
The only way I could think to handle this was to do:
def show
authorize! :destroy, :journey
end
So that it checks that method against a different permission. But I'd like to avoid having to do that if possible.
Is it possible to alias a method in only one controller to another? And not alias for all controllers. Looking at the docs I can't see this.

undefined method `save' for 1:Fixnum [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I made some variables that is related to models and I want to save the new variable relating to the control structure, but I can't. It said "NoMethodError - undefined method `save' for 1:Fixnum:".
What I want to make is that the function if This program get 4 people, It will show the member name for that members. 5th member will be in the next group.
Anyone can solve this?
or if you need more information, please let me know.
Thanks
This is Waitinglists_controller
class WaitinglistsController < ApplicationController
before_action :authenticate
def new
#waitinglist = current_user.created_waitinglists.build
end
def create
#waitinglist = current_user.created_waitinglists.build(waitinglist_params)
if #waitinglist.save
redirect_to waitinglist_waiting_path(#waitinglist, #owner)
else
render :new
end
end
def waiting
#group_number = Waitinglist.select(:count_number).last
#already_group_people = Waitinglist.where(count_number: #group_number).count
#current_person_group_number = current_user.created_waitinglists.select(:count_number)
#current_group_people = Waitinglist.where(count_number: #current_person_group_number).count
case #already_group_people
when 0
#current_person_group_number = 1
#current_person_group_number.save
when 1..2
#current_person_group_number = #group_number
#current_person_group_number.save
when 3
#current_person_group_number = #group_number
#current_person_group_number.save 
redirect_to show_waitinglist_path
when 4
group_number += 1
#current_person_group_number = #group_number
#current_person_group_number.save
end
end
def show
#current_person_group_number = current_user.created_waitinglist.select(:count_number)
#matched_people = Waitinglist.find(count_number: #current_person_group_number)
#matched_people == 0 if #matched_people = nil
end
private
def created_by?(user)
return false unless user
owner_id == user.id
end
def waitinglist_params
params.require(:waitinglist).permit(:look_like, :id)
end
end
This is Sessions controller for User loggin
class SessionsController < ApplicationController
def create
user = User.find_or_create_from_auth_hash(request.env['omniauth.auth'])
session[:user_id] = user.id
redirect_to root_path
end
def destroy
reset_session
redirect_to root_path
end
end
Application contrtoller is this
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
helper_method :current_user, :logged_in?
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
def logged_in?
!!session[:user_id]
end
def authenticate
return if logged_in?
redirect_to root_path
end
end
Under codes are for models
class Waitinglist < ActiveRecord::Base
belongs_to :waiting_person, class_name: 'User'
after_initialize :init
def init
self.count_number ||= 1 #will set the default value only if it's nil
end
end
class User < ActiveRecord::Base
has_many :created_waitinglists, class_name: 'Waitinglist', foreign_key: :owner_id
def self.find_or_create_from_auth_hash(auth_hash)
provider = auth_hash[:provider]
uid = auth_hash[:uid]
name = auth_hash[:info][:name]
image_url = auth_hash[:info][:image]
User.find_or_create_by(provider: provider, uid: uid) do |user|
user.nickname = name
user.image_url = image_url
end
end
end
It's quite clear to me. You call save on #current_person_group_number, which is instance of Fixnum, so it doesn't have save method defined.
Unfortunately the code you wrote makes very little sense and it is pretty hard to understand what you're trying to do here.
Firstly, you overuse instance variables. If you're not gona use them in another methods (it is hard to say as you haven't post rest of your class)
Secondly, you overuse select method.
#group_number = Waitinglist.select(:count_number).last
All it does is changing the SELECT statement when querying the database for models, but it still returns the model, not a number or field value. So #group_number is not a number - it is a WaitingList instance. If you want a number do:
group_number = WaitingList.last.count_number
(posting now as question may be closed in a second. Will update later if that won't happen)
You can only save the ActiveRecord objects, which means you need to have it somewhere. Apparantly you want to update #current_person_group_number, however you can't reassign this variable to do the trick. You have to get the whole model, change its attribute and then save the model. It would look sth like:
current_waiting_list = current_user.created_waitinglists.last # This seems to be a collection, you need to tell here which waiting list you want to get from this collection
current_waiting_list.count_number += 1
current_waitin_list.save
My last point is - please look into act_as_list gem. Since you're creating waiting list it is a must have gem for you.

Blocking Users From Specific Pages using Ruby on Rails and cancan

I am learning Ruby on Rails and was looking into utilizing cancan to help restrict users access to actions that they shouldn't have and to pages depending on who they are. I currently understand how to restrict actions, but I was curious if someone could help with actually restricting certain pages and unique pages.
One example is I have a home page for admin users and one for regular users, how would I restrict the admin page from the normal user?
Thanks, and any pointers on if I am doing something wrong is greatly appreciated.
If you want to use cancan :
Admit you add in your user controller a method admin_home :
def admin_home
#user = current_user
authorize! :admin_home
end
You need to specify in ability.rb file you want to restrict access to admin_home for standard users :
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user (not logged in)
if user.admin?
#Authorize all actions
can :manage, User
else
#authorize only self modifications and restrict access to admin_home
can :manage, User, :id => user.id
cannot :admin_home, User
end
end
end
You can find great resources about cancan in official wiki like
https://github.com/ryanb/cancan/wiki/Defining-Abilities and
https://github.com/ryanb/cancan/wiki/Authorizing-controller-actions
Hope this help
Note: I am just giving you an example, you are not supposed to use it as it is, but you can have an Idea that how you will be able to put your logic.
class AdminsController < ApplicationController
before_filter :check_admin, :only => [:index, :show]
def index
#admins = //whatever your query for this action
end
def show
#admin = //whatever your query for this action
end
protected
def check_admin
if(my_condition to check if user type is admin)
{
return true // or anything u want for ur admin user
}
else
{
//anything here when user is not admin
1. you can redirect to users home page using redirect_to
2. you can redirect to a specific page which shows "You are not authorized to see this web page"
}
end
end
end

Strong parameters and Nested Routes - Rails 4.0

I have no idea how this works in rails but I set up routes like this:
resources :users do
resources :api_keys
end
(User has_many: api_keys, api_key belongs_to: user)
So I then (since I only care about API Keys), created the following controller:
class ApiKeysController < ApplicationController
before_action :authenticate_user!
def index
#user = User.find(params[:user_id])
#api_key = User.apikeys
end
def create
#user = User.find(params[:user_id])
#api_key = ApiKey.new(create_new_api_key)
create_api_key(#api_key, #user)
end
def destroy
destroy_api_key
end
private
def create_new_api_key
params.require(:api_key).permit(user_attributes: [:id], :api_key)
end
end
Which states, authenticate user before every action, index fetches all api keys based on a user id. create is suppose to create an api key based on a user id, (note: create_api_key(#api_key, #user) just an abstracted method that states - if we saved, redirect to user_path with a message, if we failed, back to user path with a error message)
And destroy, well that just finds an api key, destroys it and redirects (again with the abstraction).
Whats the issue?
the create_new_api_key method. Its freaking out and saying:
syntax error, unexpected ')', expecting => (SyntaxError)
I thought this is how I pass in the user id ??
You need to change the order of the arguments passed in to permit to fix the syntax error:
def create_new_api_key
params.require(:api_key).permit(:api_key, user_attributes: [:id])
end

in UsersController#create, User.new(params[:user]) return an empty User (params looks good)

I'm kind of new to Rails 3.1. and I'm facing an issue only in my production env with my Signup form (actually, it's more about the controller).
Here is the code in User
class UsersController < ApplicationController
[...]
def create
#user = User.new(params[:user])
logger.info "value of login in param : #{params[:user][:login]}" #-> log the actual login
logger.info "value of login : #{#user.login}" #-> log empty
#user.admin = false
if #user.save
flash[:notice] = t('flash.notice.user.create.valid')
redirect_back_or_default root_path
else
flash[:notice] = t('flash.notice.user.create.invalid')
render :action => :new
end
end
end
Also, the controller logs show that the params hash is good
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"QwOqmp0CT/d4mmC1yiLT4uZjP9bNDhbUXHanCQy5ZrA=",
"user"=>{"login"=>"myLogin",
"email"=>"t.r#gmail.com",
"password"=>"[FILTERED]",
"password_confirmation"=>"[FILTERED]"}}
My login form works as expected (already created users are able to sign in)
Again, this only happens in production.
EDIT: Here is my User Model
class User < ActiveRecord::Base
acts_as_authentic
#== Callbacks
before_create :set_defaults
attr_accessible :avatar ##### EDIT: TO FIX THE ISSUE, ADD THE OTHER FIELDS AS WELL
protected
def set_defaults
self.total_1 = self.total_2 = self.total_3 = 0
end
end
Just to memorialize the answer from the comments above:
Normally you can use mass assignment to set fields on a model, but when you use attr_accessible, you are then limited to only mass assigning those fields. So stuff like User.new(params[:user]) won't work; instead, you'd have to do:
#user = User.new
#user.login = params[:user][:login]
# ...etc.
#user.save
Simple add your fields to the attr_accessible list and you can go back to mass assignment.

Resources