How to customize active admin comments feature in rails 3 - ruby-on-rails-3

I need to send an email whenever the admin add a comment to a user.
I am using active admin 0.4.3
How can I get this event and send email. When I post a comment, In my console I can see the following actions performed
Started POST "/admin/comments"
Redirected to http://localhost:3000/admin/comments/182
Started GET "/admin/comments/182"
Started GET "/admin/accounts/227"
I dont know how to access these functions. Please help.

I got it working by adding this code into your config/initializers/...
module ActiveAdmin
class Comment < ActiveRecord::Base
after_create :send_email
def send_email
AdminMailer.comment_created(self.id).deliver
end
end
end
Please mind that you have to write the AdminMailer and that we only pass the id because our mailer uses redis to send the mail asynchronous. If you don't have this you can pass the object.
I tried to overwrite the create action of the Admin::CommentsController in the same way but it didn't work. It would be much nicer to have this in the controller because sending an email is more a business of the controller than of the model. Any ideas how to do this?
...ok...commented on an active admin issue which adresses the same question and got some good answers...

As this is controller logic the best is to put it in the controller.
You can take a look at https://github.com/activeadmin/activeadmin/issues/2493#issuecomment-24892236
Basically, for modifying the Comment controller you have to do it after loading:
ActiveAdmin.after_load do
ActiveAdmin.register ActiveAdmin::Comment, as: 'Comment' do
controller do
after_action :send_email, only: [:create]
def send_email
AdminMailer.comment_created(self.id).deliver
end
end
end
end

Related

Creating an action inside a controller, after it has been generated

I am working on a rails app, and have generated a Controller via
rails g controller Pics index upload
but now I would like to add another action
delete
do I do this by manually adding a delete method in the Pics controller?
Or do I need to run another generation. My concern is that by adding manually something may not get included (not sure what it would be, but something under the hood.)
Is this the best way of adding a new action to a generated controller?
If you add manually, just make sure you have the right route on your routes.rb.
Let's say you create your delete action inside your Pics controller.
def delete
# do stuff
end
On your routes.rb, you need to append the route to your resource like this, remembering to analyse if it is a resource that acts upon a member of your resource, or a collection. (More about this you can read on this guide http://guides.rubyonrails.org/routing.html#adding-more-restful-actions).
resource :pics do
collection do
post :delete
end
end
Or
resource :pics do
member do
post :delete
end
end
Remember that all RESTFUL actions are handled by default by the rails router, again, try to read the guide i showed earlier for precise information about the topic. Hope it helps.

Devise: Load a partial instead of showing a notice for non confirmed members

Is there a way to load a view for no confirmed users that login?
Default behaviour is to show a notice: " You have to confirm your account before continuing."
I tried
overrule the sessions#create method of devise checking for current_user.confirmed_at.blank?
in the after_singin_path check for current_user.confirmed_at.blank? and render the view instead
My goal is to render a custom view instead of the notice but cannot hook into the right location. Who knows how to accomplish this? thx!
You can simply copy the code from the devise github and place in your controllers/devise. then change any action or method you want to.
You may also just extend the devise session controller and override any action you want to.
class Abc < Devise::SessionsController
# this just reopens the class.
# Remember classes are never "closed" in ruby!
end
I like the ruby way of solving this, I guess that in your UsersController after a POST request the user will be returned and signed in using the sign_in(Object) helper Devise provides.
Also I suggest using a confirmed boolean instead of timestamp.
Why not check for the value using an if else statement the ruby way:
user.confirmed ? sign_in(user) : render :partial => 'path/partial'
Hope this might help you out

Devise on rails 3 how can I trigger a custom code to run as soon as a user sign up?

I have an action (send_confcode) that will send a confirmation code via sms as soon as a new user signs up. I would like to know where this action should be placed. Is it under the User model generated by Devise?
def send_confcode
#confcode = (Time.now.to_i).to_s.slice(6,9)
# more code here for sending code via an sms api
end
Use an after_create callback method in your User model. Add this to your user model:
after_create :send_confcode
After a user is created it will call the send_confcode method.
You can read more about Rails callbacks here: http://guides.rubyonrails.org/active_record_validations_callbacks.html#callbacks-overview

Rails 3 - Routing to a user profile

Greetings all, newbie to Rails here. I'm currently having issues routing /profile to the current user's profile.
My route is as follows:
match "profile" => "users#show"
However, this is hitting me with the "Couldn't find User without an ID" error. I know it has to do with my show method in the Users Controller. That code is simply:
def show
#user = User.find(params[:id])
end
Now, I could add another method in my Users controller with "#user = current_user" and it works fine. However, it seems a bit redundant and would also require a copy of the show view page. From what I've gathered with Rails, it's all about keeping things neat and tidy.
I would appreciate it if someone could point me in the right direction. Thank you.
RailsGuides states:
Because you might want to use the same controller for a singular route (/account) and a plural route (/accounts/45), singular resources map to plural controllers.
So I think you want to change your code to be the following
def show
#user = !params[:id].nil? ? User.find(params[:id]) : current_user
end

Passing controller method attributes in before_filter methods in Rails 3

I'm trying to only allow access to galleries by users who have permission to view them. Galleries have many shared_users through permissions, and vice versa. Galleries also have only one owner. Owners and shared users are both of the User class. This all works fine. The issue that I'm having, however, is with my access filters.
I'm using the following code to see if a user is allowed to see the gallery they are trying to access:
def authenticate_viewers!
if user_signed_in? && current_user.can_view?(#gallery)
return true
end
redirect_to root_url,
:notice => "You must have permission to view this gallery."
return false
end
As you can see, can_view? requires the #gallery that I'm setting up in the show method, but a before_filter won't let you access the attributes set up in the method, since it resolves before the method executes. Using an after_filter works, as long as an unauthorized user doesn't try to view the gallery. If it does, I get a DoubleRender error, since after_filter allows the page to render, then tries to redirect.
I just thought that I could perhaps use params[:id] instead of #gallery, though I haven't tried it yet, and ultimately this may be more efficient (passing an integer instead of an object). In any case, is there a way to make my current code work? or is it in my best interest to switch to using the params (if that's even going to work)?
Wow, okay. It's really helpful just to start writing questions here on SO, because as I do, I typically get a brainstorm of how to solve the problem. Instead of using the #gallery object, I just use a Gallery.find(params[:id]) and everything works like a charm. Thank God I don't have to rewrite all my code.