Devise Current User Can't Get Nested Data to Show in View - ruby-on-rails

I'm trying to make an example app to learn about namespace/scopes/modules
Normally I would user current_user helper but I have Client::Addresses nested in behind and would like to grab say the user's city and just display it on their edit page (devise registration/edit screen)
<%= current_user.?? %>
Using the line below. I also added inverse_of as my understanding it'll reverse the relationship as well but no avail.
<%= #user.addresses.cacity %>
I think this is pretty close #user.id works but adding the rest error reads. Looks like I also dealt with strong params just not sure. I'm doing this to practice namespacing:scopes/modules:
undefined method `cacity' for #<ActiveRecord::Associations::CollectionProxy []>
It would be great to do something like.
<%= current_user.addresses.cacity %>
Here's some additional information with what I got so far, let me know if additional info is needed.
routes.rb
Rails.application.routes.draw do
namespace :client do
resources :subscriptions
end
# Security Devise Setup
devise_for :admins
devise_for :users
# Main Pages
root 'website/page#index'
# Client Sections
resources :users do
scope module: "client" do
root :to => 'dashboard#index'
resources :addresses
end
end
namespace :admin do
root :to => 'panel#index'
end
end
user.rb
class User < ActiveRecord::Base
include Gravtastic
gravtastic
# Devise Settings
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
# Model Relationships
has_many :addresses, :inverse_of => :user, class_name: 'Client::Address'
end
client/address.rb
class Client::Address < ActiveRecord::Base
belongs_to :user, :inverse_of => :addresses
end

#user.addresses
is a collection, and you send a (instance) method cacity to a collection, which, as errors states, do not respond to it.
#user.addresses.first.cacity would work.
You could limit the relation to has_one:
has_one :address #...
Which will allow you to use the following:
#user.address.cacity

Related

Set different route page for non admin users (attribute) (devise gem on ruby on rails)

Im currently learning ROR and have bumped into a small issue regarding different root pages depending on the user type. In my user model i have an attribute for admin which is either true or false depending on the user.
Please see my routes file below, currently all users aways go to 'houses#index', even if they have admin set as false.
I cannot see where i am going wrong in my routes file.
Is there anyway to add a condition for attribute admin on authenicated user in my routes file?
Routes.rb
Rails.application.routes.draw do
devise_for :user
get 'welcome/index'
resources :houses
resources :tenants
resources :requests
authenticated :user do
root 'houses#index', as: "authenticated_root"
end
authenticated :user, {admin:'false'} do
root 'requests#index', as: "authenticated_root1"
end
root 'welcome#index'
end
model\User.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :houses
has_many :tenants
has_many :requests
def admin?
admin
end
end
Thanks.
You should use after_sign_in_path_for devise's method in your application_controller.
https://github.com/plataformatec/devise/wiki/How-To:-redirect-to-a-specific-page-on-successful-sign-in
For instance:
def after_sign_in_path_for(resource)
stored_location_for(resource) || (resource.admin? ? admin_dashboard_url : user_dashboard_url(resource))
end
(Please note that resource is like an alias for the user instance. By default it's the first devise role declared in your routes as said here: https://stackoverflow.com/a/40825885/10347572)
For all other requests, if you're not using Cancan, create a new method (pretty similar to the one above) to redirect the user according to his type (but if a user wants to access to an admin page, you should raise a 404 and not just a root redirection)

has_and_belongs_to_many association confusion

So I have an application that has a blog model,and a user model.
Now users can subscribe to many different blogs, and users can also create many of their own blogs.
What would the association look like?
Right now my models look like the following:
Blog.rb:
class Blog < ActiveRecord::Base
has_and_belongs_to_many :users
has_many :posts
end
User.rb:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable,
:validatable
has_and_belongs_to_many :blogs
validates :email, uniqueness: true, presence: true
validates_presence_of :password, on: :create
end
the user table has a blog_id:integer field, and the blog has a user_id:integer field.
Is this right?
And how would the commands work? I.E:
u = User.last
b = u.blogs.build(title: "bla")
b.user (shows the owner of the blog)
b.users (shows the users that have subscribed to the blog)
Ultimately, I'd like to allow users to subscribe to other peoples blogs, and create their own.
You are going to want to add a third model 'Subscriptions'. Then you are going to want to use the 'has_many_through:' association. Please read this section of the rails guides for a detailed example. http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association.
After you create the associations you are going to want to do something along these lines:
1) make sure you nest the 'subscriptions' routes underneath the blog route properly.
resources :blogs, only: [] do
resources :subscriptions, only: [:create, :destroy]
2) Create a _subscription.html.erb partial in app/views/subscriptions
3) Render the partial in blogs#show
<%= render partial: 'subscriptions/_subscription, locals: {blog: #blog}
4) Add the ability to add (create) a subscription in the partial: (this is only to add subscription, you will want to also add ability to remove)
<%= link_to [blog, Subscription.new], class: 'btn btn-primary', method: :post do %>
<i class="glyphicon glyphicon-star"> </i> Subscribe
<% end %>
5) Add 'create method' to subscriptions_controller.rb
def create
#blog = Blog.find(params[:blog_id])
subscription = current_user.subscriptions.build(blog: #blog)
if subscription.save
# Add code
else
# Add code
end
end
This should be enough direction to get you to the finish line. Good luck :)

NoMethodError in Controller#new

Hi everyone Im working in my app and I run into this error
NoMethodError in GasStationsController#new
undefined method `gas_stations' for #<Class:0x12cf77510>
Rails.root: /Users/Users/Documents/myapps/app1
Application Trace | Framework Trace | Full Trace
app/controllers/gas_stations_controller.rb:4:in `new'
I dont understand if my routes are ok. I put my routes.rb and my GasStationsController
Estaciones::Application.routes.draw do
root :to => "static_pages#home"
match '/contact', :to=>'static_pages#contact'
match '/about', :to=>'static_pages#about'
devise_for :users
resources :users do
resources :gas_stations
end
....
user_gas_stations GET /users/:user_id/gas_stations(.:format) gas_stations#index
POST /users/:user_id/gas_stations(.:format) gas_stations#create
new_user_gas_station GET /users/:user_id/gas_stations/new(.:format) gas_stations#new
edit_user_gas_station GET /users/:user_id/gas_stations/:id/edit(.:format) gas_stations#edit
user_gas_station GET /users/:user_id/gas_stations/:id(.:format) gas_stations#show
PUT /users/:user_id/gas_stations/:id(.:format) gas_stations#update
DELETE /users/:user_id/gas_stations/:id(.:format) gas_stations#destroy
as you see the method is there "gas_stations"
I only have this on my controller
class GasStationsController < ApplicationController
def new
#user = User.find(params[:user_id])
#gas_station = #user.gas_stations.build
end
end
User model
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :name, :email, :password, :password_confirmation, :remember_me
# attr_accessible :title, :body
has_many :cars
validates_presence_of :email
end
As the error says, Rails has no idea what gas_stations are as it pertains to a user. You need to set that association:
class User ...
...
has_many :gas_stations
...

Creating comments that belong to their respective microposts and users (in an app using Devise)

Right now, I have two models: User and Micropost.
The User model is working with Devise.
Example of the files involved:
user_controller.html.erb:
class PagesController < ApplicationController
def index
#user = current_user
#microposts = #user.microposts
end
end
index.html.erb:
<h2>Pages index</h2>
<p>email <%= #user.email %></p>
<p>microposts <%= render #microposts %></p>
microposts/_micropost.html.erb
<p><%= micropost.content %></p>
micropost.rb:
class Micropost < ActiveRecord::Base
attr_accessible :content
belongs_to :user
end
user.rg:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
has_many :microposts
end
Now I want to create comments for the microposts:
Each comment should belong to its respective micropost and user (commenter). Not sure how to do this (is it a good situation to use polymorphic associations?).
An user should have many microposts and comments (not sure how to co this either).
I have no idea how to make it so that the comment is made the the user who is currently signed in (I think I have to do something with Devise's current_user).
Any suggestions to accomplish this? (Sorry, I'm a Rails beginner)
No, nothing you've said suggests that you need polymorphic associations. What you need is a comments model with a schema something like the following:
create_table :comments do |t|
t.text :comment, :null => false
t.references :microposts
t.references :user
t.timestamps
end
And then
# user.rb
has_many :microposts
has_many :comments
# microposts.rb
has_many :comments
You will probably want nested routes for your comments. So, in your routes.rb you'll have something like
#routes.rb
resources :microposts do
resources :comments
end
.. and in your comments controller, yes, you'll assign the value of comment.user something like the following...
# comments_controller.rb
def create
#comment = Comment.new(params[:comment])
#comment.user = current_user
#comment.save ....
end
You might want to look at the Beginning Rails 3 book, which would walk you through this.

Devise Signout Routing Error

I'm using Devise 1.5.1 in a Rails 3.0.3 app. It works well, with one exception: The signout link gives me this error:
Routing Error
uninitialized constant UsersController
The link that leads to this is:
<%= link_to('Logout', destroy_user_session_path, :method => :delete) %>
I haven't created an app/controllers/user_controller.rb file, but my understanding that this wasn't necessary when using Devise, correct?
In case it's relevant, my routes.rb file looks like:
Su::Application.routes.draw do
get "group/create"
devise_for :users
resources :users
resources :payers
resources :payments
resources :categories
resources :groups
match "adduser", :to => "groups#adduser"
root :to => "pages#home"
end
...and app/models/user.rb looks like:
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :first_name, :email, :password, :password_confirmation, :remember_me, :group_id
end
I have googled and searched on SO extensively, but to no avail. How should I troubleshoot something like this?
In your routes file, you have
devise_for :users
which serves for the routes for Devise, but
resources :users
is a generic CRUD route, which makes Rails to think that in your app, you have Users Controller, and that you are doing something with the Users model in your model.
The error tells that you don't have a Users Controller and that's true, but it's looking for it because of the route.
So, either delete the line or add a Users Controller if you want to do something with the Users model.
If anything is not clear, post it as a comment.

Resources