I tried following this, but could not get it to work. I want to create a total custom site in admin (superuser login protected).
Here is what I tried:
admin.py:
class CampaignAdminSite(AdminSite):
def get_urls(self):
custom_urls = [re_path("campaigns/", self.admin_view(my_view)),]
urls = super().get_urls()
return custom_urls + urls
def my_view(request):
return render(request, 'admin_campaign.html'
I hoped for the extra link campaigns to show up as an item in the admin first page - but I do not see anything, and I cannot go to the link by directly addressing it in the navbar. Do I need more?
Related
I have an app that is using Devise, I would like that after a user signs up, they are directed to a specific page, this page calls an API and saves the value from the API, I need this page to only be accessible or available after a user completes the sign-up form and clicks submit, and is then redirected to this page.
I do not want this page or URL accessible any other way but after sign-up, as the API will send a new value if accessed again. How can I accomplish this?
Once a user signs up they will be redirected to the page calling the API:
def after_sign_up_path_for(resource)
api_call_path ##path that can only be accessed after sign_up
end
The API is called and the response from the JSON data is automatically saved to the database once the page is opened, if the page gets opened again a new JSON response will be received with new data, which is what I would like to avoid.
So in a nutshell, my question is how can I restrict access to a specific path, and only make that path accessible if a user completes the sign-up form (devise) OR is there a way that I can run the code from the controller using a callback/filter after the user is created through the User model?
I was just busy with something similar. You do not need to direct the user to a page to run the code, you can just run the code that needs to be run after the user logs in the first time.
You need to create a Session Controller, and create a conditional statement that checks if the user has logged in previously:
#config/routes.rb
devise_for :users, controllers: { sessions: "sessions" }
#app/controllers/sessions_controller.rb
class SessionsController < Devise::SessionsController
def after_sign_in_path_for(resource)
if resource.sign_in_count == 1
##Do something awesome
else
root_path
end
end
end
As Emmanuel advised you can check futher info on the Devise Controllers.
Let's call the moment between after sign_up and showing the specific page - state A. So in the specific page controller you need to know - is the user in state A. You can achieve it by
1) saving to db (server side) that user is in state A after sign up and resetting state after showing specific page (you can do resetting triggered by client side to guarantee that page is showed).
2) saving to cookies (client side) after sign up then do as above.
Second solution is more clean in my opinion, but I do not know how strict is the rule to show only once
You can customize devise users controller by issuing
rails generate devise:controllers [scope]
Then customise UsersController such that after user is saved you can call your api code there
eg
def create
#user = ....
if #user.save
#user.call_api_method()
else
......
end
end
For more information check Configuring controllers
If you go to Twitter.com when you are not logged in, you will see the marketing page with the login & registration fields.
However, if you go there when you are logged in, you will see your activity stream for your Twitter handle.
I know one way to do this in Rails is to have a home/index for the logged in users, and just use public/index.html for the marketing site. But Twitter is not using public/index.html, so I am wondering how they do it?
Is it just a simple case of having one root route, but then an if statement that displays two different pages depending on whether or not the user is logged in?
Or is there some other more fancy routing trick that I can use to do that?
If it is just an if-statement, that seems a bit hacky...no?
Thanks.
This might give a head start. http://collectiveidea.com/blog/archives/2011/05/31/user-centric-routing-in-rails-3/
By default controller methods that handle specific routes render a view that has a corresponding name (home/index route links to home controller and index action which in turn renders the view index.html.erb inside the app/views/home folder).
However, inside the controller method that handles the root request you can simply render a different view based on the fact that a user is logged in or not.
You would probably have something like this:
class HomeController
def index
...
if user_logged_in?
render "logged_in_user"
# else it will render the index view by default
end
end
end
In this case "logged_in_user" would be a different view (template or html.erb file) from the app/views/home folder.
For more information take a look here: Rails rendering guide
it can some kind of redirect for not logged in users to different controller , checking of user session can be done in before_filter
I use this code, it get all pages the user likes:
#user = session[:graph].get_object('me')
like = session[:graph].get_connections("me", "likes")
if !(like.to_s.include?('appid'))
redirect '/youneedlike'
end
It's works for me and my mates, but some users have error: they are always redirected, even though they like our page.
What's wrong?
Does your app request the user_likes permission?
Alternatively, if your app is a canvas app, you can use the signed_request parameter to do the same thing:
# pseudocode
signed_request = decode signed_request()
if signed_request['page']['liked']:
# user liked page, do something cool
else:
# user doesn't like page. redirect somewhere to tell them why they should
i'm design a shopping cart,there are two web page,
first is checkout page,and the second is order_success page
if user use the go back button on webbrowser then it will go back to checkout page after user have go to order_success page.
so i want to find some way to forbidden let use go back,
is there some way on rails to archieve this?
"i know this but user will use the go back button,if there some cache in client,
user still could see something & re-submit, this is not what I expect" [was that the meaning?]
If you want to prevent the user resubmit the same request, you may add a hidden field (just something random) and store it in a session after the request has been processed:
if params[:token] == session[:used_token]
render_already_processed_notice
return
end
if #cart.save
session[:used_token] = params[:token]
....
If you use a cart ID in a request, then you just may use the status of the Cart model:
#cart = Cart.find(params[:id])
render_some_notice and return if #cart.done?
....
#cart.done = true
#cart.save
Personally I would not create a checkout and order_success pages. I would just create a single page - cart status, and depending on the model status I would just display different content.
If some action may be executed only once (like closing the cart or finalizing the transaction) there is no problem: render_something and return if #cart.already_closed?
On pages, where multiple submits are possible, but not always welcome (like adding a product to the cart - the user can add two identical products) you may do two things:
1) Use the mentioned token, which will detect when the user just pressed F5, and ask him whether the action really should be done twice, or
2) Just accept the requests, but always provide the user with methods to 'rollback' the actions (allow him to delete products from the cart), and ensure that the cart content will be verified before final acceptance.
clear shopping cart
redirect user to new action
After a purchase is successful you should clear the shopping cart and then redirect the user to a new action.
In your order_controller.rb
def create
#shopping_cart = nil
redirect_to some_path
end
I followed the tutorial exactly: http://github.com/binarylogic/authlogic_example
But I am wondering how can I get the login form to appear on all pages when someone isn't logged in?
I searched Google and looked at many forums for answers, but the only solutions I could find require me to define #user_session = UserSession.new for every page that has the login form.
What I'd like to do is put the form in the application.html.erb file and only have it show up when people are logged out (which I've managed to do).
However, I'd like to only have to put #user_session = UserSession.new in one controller, such as the ApplicationController, as it is very non-RESTful to have to put that piece of code on every single page. If I leave the form code in the application.html.erb and that code is not defined for a page in the controller, then the page will give an error.
I don't want to have to define it for every page, as it will be a lot of work to have to remove it from every single page if I ever decide to get rid of the login form or something.
In short: I want to put the Login form on every single page of my site, and only have to put #user_session = UserSession.new in one controller.
Thank you.
In ApplicationController, you can do the following:
before_filter :prepare_new_session
def prepare_new_session
#user_session = UserSession.new if current_user.blank?
end
That'll give you a #user_session object for every action (if a user is not currently logged in). That way, you can include the form on every page by placing it in the layouts/application.html.erb file.