User scope with Devise and Rails 4.1 - ruby-on-rails

I'm doing some proof of concepts with Rails. I created a Customer, and apply to it DEVISE.
Everythig works fine, but now i'm trying to logging with a customer and enter directly into his scope.
localhost:3000/customers/1
After this hide the /customers/1 with some word, for example: myProfile.
I'm trying to do the first part with
module ApplicationHelper
protected
def after_sign_in_path_for(resource)
#path to redirect
end
end
I was trying with definitions from routes.rb
redirect_to(customers_path)
or something like:
#customer= Customer.find_by_email(current_customer.email)
redirect_to(customer_path(#customer))
But nothing is working yet.
I'm not sure how to send messages to the console of the server (like in Java with some System.out.println) to check the contents...
Thanks a lot!

Related

In Rails, how would I show a 'Goodbye' page that is *only* accessible immediately after the user signs out?

I was recently using Svbtle.com where they show a page immediately after logging out. It says "Goodbye.", along with link to go "Back to SVBTL".
I like the idea of a 'farewell' page, similar to how they did it, and would like to do something similar in a project I'm working on.
The 'farewell' page on Svbtle has a path of https://svbtle.com/notify?logout. When you reload the page or try to navigate to https://svbtle.com/notify?logout, it redirects you to the site landing page.
What is this magic?
How would I go about only showing a page upon user logout, but then prevent them from visiting it otherwise?
I'm using Rails 5.0.0.1 and Devise for authentication.
Create a static goodbye page with whatever content you want. Edit your routes.rb and give the goodbye page a route (we'll call it goodbye_page_path for illustrative purposes here).
Go into app/controllers/application_controller.rb and create a method called after_sign_out_path_for, which is a standard Devise helper. Set it up like this:
def after_sign_out_path_for(resource_or_scope)
goodbye_page_path
end
That should redirect users to your goodbye page whenever they log out.
To prevent access to the goodbye page, store a flag in the session object. In the controller method handling logout:
session[:goodbye] = true
In the controller method that handles displaying the goodbye page:
def goodbye_page
if session[:goodbye] && session[:goodbye] == true
render 'goodbye_page'
end
end
I started implementing this and wanted to share what I went with. I tried writing to session initially but ran into problems as session wasn't available after logout where the GoodbyeMessagesController scope lies. I ended up going with a cookie that is set immediately after sign out, then deleted in my goodbye controller:
ApplicationController
def after_sign_out_path_for(resource_or_scope)
cookies[:single_view_page] = true
goodbye_path
end
GoodbyeMessagesController
def show
if cookies[:single_view_page]
cookies.delete :single_view_page
# Other logic...
else
redirect_to root_path
end
end
It ended up being super easy, and it works great.

Adding NEW controller to a Ruby on Rails 4 Spree -Ecommerce application

I am trying to add a new controller a Ruby on Rails 4 Spree -Ecommerce application. First of all, in routes.rb I added root :to => 'login#login' then in app/controllers/ I added a file called login_controller.rb and in the file I added the following code.
module Spree
class LoginController < Spree::StoreController
def login
render('spree/shared/_login')
end
end
end
When I start the server and go to localhost:3000/ I get this error
Unable to autoload constant LoginController, expected superclass mismatch for class LoginController
My goal here, is to require login to even view the home page of the store. I am attempting to build a site where users get a login screen when the go to it unless they are already logged in.
Please know that I am ruby noob and this is actually my first ruby on rails application so I am completely clueless here.
Also if there is a better way to go about doing what I want (requiring a login to basically view any page on the site) than my current apporach (having a LoginController which checks if there is a user logged in - if so redirect to home, if not redirect to Login) please let me know.
P.S. I got the layout for the controller from the home_controller.rb in the spree gem
I have not tested the code, but I suggest you use Spree's Devise integration
then you can add a before filter mandating authentication. Create a decorator to contain this logic addition. Create a file called base_controller_decorator.rb inside app/controllers/spree with the following code:
Spree::BaseController.class_eval do
before_filter :check_logged_in
def check_logged_in
unless spree_current_user
redirect_to spree_login_path
end
end
end
I guess if you are in the Spree module you don't need the namespace for the superclass class LoginController < Spree::StoreController like so class LoginController < StoreController.

How to run class method via URL in Rails 4

I'm real beginner in Rails.
I created app/services/xclass.rb class with some_method inside.
I need to execute some_method using url.
For example, I want run this method when I execute in my browser url - http://application.com/notifications/send
I think it could be done through controller (notifications_controller) but how to do it?
I created only controller, with no model, just for launching some_method.
first, create a route:
get "notifications/send" => "notifications#some_action", :as => "send_notification"
Then create a controller action in your controller (ie. NotificationsController):
def some_action
Xclass.some_method # run the method you want
redirect_to root_path # redirect or whatever you want here
end
Now you can either visit the path http://your_app.com/notifications/send, or link to is using 'send_notifications_path' url helper in rails.
That should do it
Since you're a beginner, let me give you some ideas
MVC
Firstly, you need to appreciate that Rails is an MVC (model view controller) framework:
In short, this means that every time you send a "request" to Rails, it will be "routed" to the specific controller action which corresponds with that route.
This means that when you ask about how to fire a "class method", you're going to have to work within the confines of the MVC programming pattern. Here's how:
#config/routes.rb
resources :notifications do
get :send, on: :collection #=> domain.com/notifications/send
end
#app/controllers/notifications_controller.rb
class NotificationsController < ApplicationController
def send
#call your class method here
YourModel.class_method
end
end
#app/lib/your_model.rb
class YourModel
def self.class_method
#do something here
end
end
--
Rails
This is further supported by the fact that Rails is just a framework - in fact it's a gem (a great one) which runs on top of Ruby.
This means that even though some of the ways in which Rails works might seem somewhat alien to begin with, you have to remember that it basically just captures "requests" fed to it by a web sever, processing them with connectivity to the database etc.
The issue here is that as you're sending the request over HTTP, you have to work within the constraints of this protocol (specifically that it's stateless), and with Rails. As mentioned, Rails is MVC-based, which means that every request will be routed to your controller, which is why you have to create the corresponding route & controller action to handle it
If you use the code above (tweaked to your app), it should work for you

Adding subdomain for different user types

I am pretty new to Rails and most of my knowledge depends on tutorials :)
So, I followed this http://www.railstutorial.org tutorial and created really good site but now I run into a problem. For my users I have a special column in my database which shows which type of user he is. For example I have column 'student' which is 'true' if user is student and 'false' if he's not.
Now I would like to create a subdomain for students. So, when student wants to sign up or sign in he would be transferred to www.student.mysite.com instead of www.mysite.com.
How can I accomplish that?
Thank you :)
There are a number of ways to do this, specifically you'll be interested in looking up multi-tenancy in respect to rails
--
Multi Tenancy
Whilst multi tenancy is typically the definition of having multiple databases / assets (one for each user), however, as it's ridiculously difficult to get this working in rails (something we're currently working on), you can use the principle with a single stack of data
There are several tutorials on how to achieve this with Rails here:
Basecamp-style subdomains by DHH (although looks like the post is down)
Multitenancy with PostgreSQL (Railscasts)
Apartment Gem (achieving multi tenancy on Rails)
Although this is not directly related to your question, most of the "multi tenancy" questions
are typically based on "how do I create different subdomains for my users"
--
Subdomains
The basis of subdomains on Rails is to capture the request, and route it to the correct controller. We've managed to achieve that using the following setup:
#config/routes.rb
constraints Subdomain do #-> lib/subdomain.rb & http://railscasts.com/episodes/221-subdomains-in-rails-3
#Account
namespace :accounts, path: "" do #=> http://[account].domain.com/....
#Index
root to: "application#show"
end
end
#lib/subdomain.rb
class Subdomain
def self.matches?(request)
request.subdomain.present? && request.subdomain != 'www'
end
end
This will give you the ability to do the following:
#app/controllers/accounts/application_controller.rb
class Account::ApplicationController < ActionController::Base
before_action :set_account
def show
##account set before_action. If not found, raises "not found" exception ;)
end
private
#Params from Subdomain
def set_account
params[:id] ||= request.subdomains.first unless request.subdomains.blank?
#account = Account.find params[:id]
end
end
Ideally, we'd love to handle this in the middleware, but as it stands, this is what we've got!
This will give you the ability to call the data you need from the #account variable:
#app/views/accounts/application/show.html.erb
<%= #account.name %>

Detectmobilebrowsers.com script -- Rails

New to Rails here. I got a short script in Rails at detectmobilebrowsers.com to check and redirect mobile browsers. It looks like:
def redirect_mobile(url = "http://detectmobilebrowser.com/mobile")
redirect_to url .....
.....
(request.user_agent[0..3])
end
It looks like this is one big function. Where should I put this in the typical Rails directory structure (app with controller, helpers, models subdirectories / components / config / etc) so that when a user accesses the front page (index), they'll get redirected to a certain mobile address?
Thanks!
You can set this up as a before_filter on your ApplicationController. This controller is inherited by all of your other controllers, so its filters run on every request.
Under app/controllers/application_controller.rb,
class ApplicationController < ActionController::Base
before_filter :redirect_mobile
private
def redirect_mobile(...)
# ...
end
end
Though, I highly suggest that you modify that script to do smarter redirects, otherwise a mobile user visiting http://www.example.com/products/123?color=green will simply be redirected to the mobile homepage, rather than the mobile version of product 123 (in green!).

Resources