nested devise user's show path helper - ruby-on-rails-5

I have nested my controller account which uses a devise user like
resources :venues do
resources :accounts
end
In my accounts controller the index is
before_action :get_venue
def index
#venue
end
def get_venue
#venue = Venue.find(params[:venue_id])
end
I have also tried my index controller as
def index
#venue.users.all
end
I would like to show all the users/accounts for this venue in my view
<%= link_to 'Show Account', venue_accounts_path(user) %>
The generated URL is
/venues/2/accounts
and I would like it to be
/venue/1/accounts/1
Running rails routes I see
venue_account GET /venues/:venue_id/accounts/:id(.:format)
accounts#show
So I assumed that venue_accounts_path(user) will give me /accounts/1/user/1 but that is not what I get.

found it
if it is a nested resource then the helper becomes
venue_account_path(#venue, user)
though I didn't find it in documentation here https://guides.rubyonrails.org/routing.html#nested-resources

Related

Rails - Devise, is it possible to use user_signed_in? without authenticate_user!?

I'm doing a sort of notepad in rails. the main page has this form for notes with the only field "content". Everyone can create a note but I'm trying to add authentication using devise so users can sign up and save their notes.
So I have my site controller with index as uniq method
site controller
def index
#note = Note.new
end
and then a notes controller with the create action
notes controller
def create
#note = if user_signed_in?
current_user.notes.build(params[:note])
else
Note.new(params[:note])
end
respond_to do |format|
if #note.save
format.js
else
format.js
end
end
end
I though that would work but devise helpers only seems to work when I add
before_filter :authenticate_user!
on the controller I need.
is it possible to check if there's a user without the before_filter? or should I make 2 create methods?
As a workaround you can try to add this before filter:
before_filter :authenticate_user!, :only => []
It might add the helpers (if it's really needed) but won't apply to any action.

Devise User Profile empty fields are shown inside the custom view

I want to show a devise user provide inside another view.
Homeprivate/profile.html.erb:
<%= render "devise/registrations/edit" %>
I just converted the default edit view into a partial. To support the user to be available as a "resource", I have the following helper.
module HomeprivateHelper
def resource_name
:user
end
def resource
#resource ||= User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
end
But if I sign in, and go to /homeprivate/profile -- I see all fields are empty. Somehow the current user is not mapped to the form. How do I map the current user to the profile view if it is displayed in a custom view? Seems like User.new is used, not the current user.
I'm fairly new to rails, but I got the same issue and figured out how to fill those empty fields. In your helper, instead of user.new use current_user. It should look like this:
def resource
#resource ||= current_user
end
That should work.

Defining a route for a method in rails 3

I'm new to Rails and currently using Rails 3, so please bear with me. I have a basic app, with a basic scaffolded controller/model e.g Contacts.
Amongst the methods for Show/Edit etc.. i have added a method called newcontacts (i have also added a newcontacts.html.erb), which will eventually show the last 5 contacts imported , but at the moment i am using the same code one would find in the basic Index method of a controller (i intend to filter the data at a later point), the method in the controller is -
def newcontacts
#contacts = Contact.all
respond_to do |format|
format.html # index.html.erb
end
end
I can access localhost:3000/contacts which displays the index method action from the contact controller, but when i try and access this method (newcontacts) using localhost:3000/contacts/newcontacts it returns the error
Couldn't find Contact with id=newcontacts
I have looked at the routes.rb file as i believe this is what needs editing, and have added the following line to routes.rb
match 'newcontacts', :to => 'contacts#newcontacts'
but this only works when i call localhost:3000/newcontacts.
So my question is, how do i get the url localhost:3000/contacts/newcontacts to work?
Any help would be great.
I think what you're trying to do is add another RESTful action.
resources :contacts do
# This will map to /contacts/newcontacts
get 'newcontacts', :on => :collection # Or (not and; use only one of these)...
# This will map to /contacts/:id/newcontacts
get 'newcontacts', :on => :member # ... if you want to pass in a contact id.
end
Try this in your routes.rb file:
resources :contacts do
member do
put 'newcontacts'
end
end
That will add in a new action for the contacts controller.

Paginate on two collections on the same model

I am planning to add some pagination to a couple of models in my application and I feel like I am missing a key concept here. Here is my application:
class Gallery < ActiveRecord::Base
has_many :photos
has_many :comments
end
class GalleryController < ApplicationController
def show
# some process here
#gallery = Gallery.find(params[:id])
end
end
I would like to be able to paginate independently on both the photos and comments for the given gallery that I am displaying. I need this to be done with AJAX and I have a feeling that calling 'show' with a parameter for photos or gallery is overkill (ie. why would I need to find the gallery if I am only looking for photos or comments).
How should I design this feature?
What is the alternative to calling GalleryController.show here?
I'd set it up like this:
class GalleriesController < ApplicationController
def index
#galleries = Gallery.paginate(params)
end
end
class CommentsController < ApplicationController
def index
#comments = parent.comments.paginate(params)
end
def parent
#parent ||= Gallery.find(params[:gallery_id])
end
end
class PhotosController < ApplicationController
def index
#photos = parent.photos.paginate(params)
end
def parent
#parent ||= Gallery.find(params[:gallery_id])
end
end
# config/routes.rb
resources :galleries do
resources :photos
resources :comments
end
Then you just request:
/galleries/1/comments
/galleries/1/photos
Check out the inherited_resources gem for this nested model pattern.
But ideally you'd want to get this all in one request. Check out this post on the Presenter Pattern in Rails.
Hope that helps.
yes, i'd absolutely recommend using inherited_resources, as it saves you a lot of boilerplate code. just set up these resources as described by viatropos, add JSON-responder (with inherited_resources, its as easy as adding respond_to :json, :html to your controller). then on the ajax side use a tempting plugin, like jquery.tmpl or mustache.js or whatever, pre-render an item template for each resource, and then use ajax to retrieve your paginated data as JSON and render it into your templates. it's incredibly easy, but if you need a step by step howto, just ask.

Rails & Devise: How to authenticate specific user?

I'm using Devise for the first time with rails, and I'm having trouble with one thing:
I used the provided authenticate_user! method in my user's controller to restrict access to pages like so:
before_filter :authenticate_user!, :only => [:edit, :show, :update, :create, :destroy]
But this allows any signed in user to access any other users :edit action, which I want to restrict to only that user. How would I do that?
In your edit method, you need to do a check to see if the user owns the record:
def edit
#record = Record.find(params[:id])
if #record.user == current_user
#record.update_attributes(params[:record])
else
redirect_to root_path
end
end
You should look into Authorization such as CanCan. Or alternatively create a new method like so:
# Create an admin boolean column for your user table.
def authenticate_admin!
authenticate_user! and current_user.admin?
end