How to show edit link only in show view using ActiveAdmin - ruby-on-rails

I want to show the link in the show view of ActiveAdmin. But it should not show up in the grid of the index view. I can't figure out how to do this. I've already tried quite a few approaches.
attempt 1
actions :all, except: proc{ params['id'].present? ? [:new, :destroy] : [:new, :destroy, :edit] }.call
this fails with undefined local variable or method 'params'
attempt 2
actions :all, only: :show, except: [:new, :destroy, :edit]
action_item only: :show do
link_to 'Edit Cash Out', "/admin/documents/#{params['id']}/edit" if params['id']
end
this fails because the route isn't being created for the edit path
attempt 3
actions :all, except: [:new, :destroy].tap do |a|
a << :edit unless params['id'].present?
end
fails with no block given

If I am not mistaken, you only want to hide the link to the edit action in the index page (in the grid).
If this is correct, one possible solution is included in this answer:
possible solution
index do
column :actions do |item|
links = []
links << link_to('Show', show_item_path)
links << link_to('Delete', delete_item_path, method: :delete, confirm: 'Are you sure?')
links.join(' ').html_safe
end
end
Just keep in mind to adjust the aforementioned code to fit the routes and naming.
Hope this works for you.

Can you please try below code?
actions :all, only: :show, except: [:new, :destroy, :edit]
action_item :view, only: :show do
link_to 'Edit Cash Out', "/admin/documents/#{params['id']}/edit" if params['id']
end

Related

Processing button on a Show view in Ruby on Rails

I have an application entity called Source on my app. This entity has a property called url.
I want to make a processing on my SHOW view. So I added a button on the show view to make a call to my controller and do this processing.
This is my routes.rb
get '/process', to: 'sources#read', as: 'read'
This is my controller method:
class SourcesController < ApplicationController
before_action :set_source, only: [:show, :edit, :update, :destroy, :read]
access all: [:index, :show, :new, :edit, :create, :update, :destroy, :read], user: :all
def read
require 'rss'
require 'open-uri'
url = #source.url
open(url) do |rss|
feed = RSS::Parser.parse(rss)
puts "Title: #{feed.channel.title}"
feed.items.each do |item|
puts "Item: #{item.title}"
puts "Link: #{item.link}"
puts "Description: #{item.description}"
end
end
render template: 'rss_reader/home'
end
And of course. My show.html.erb:
<%= button_to 'Process Source', read_path(#source), method: :get %>
<%= link_to 'Edit', edit_source_path(#source) %> |
<%= link_to 'Back', sources_path %>
</div>
When I press the "Process Source" button, it goes to the right controller method, but the object #source its not being found because of:
Couldn't find Source with 'id'=
# Use callbacks to share common setup or constraints between actions.
def set_source
#source = Source.find(params[:id])
end
What Im doing wrong here?
You are visiting the route with read_path(#source) which is expected to set the param id to the value #source.id, but you did not define your routes to support any parameter in the path.
I believe read is an action that belongs to a single instance of Source. So, you should define the route on member. This way you will be able to access params[:id] in your controller and your before_action set_source will work fine.
Change your route definition to:
resources :sources, only: [...] do # Keep the `only` array just as you have now.
get '/process', to: 'sources#read', as: 'read', on: :member
end

Two routes for the same action Rails

I have an application that lists all the subaccounts under a main account. However when I click the subaccount, instead of going to do accounts/1/subaccounts/1 I want it to go to subaccounts/1. When I use the for_each statement I get the following error. How can I click on a nested route and have it go to just subaccounts/1 instead of accounts/1/subaccounts/1?
<% #subaccounts.each do |sa| %>
<%= link_to "#{sa.name}", subaccount_path(sa) %>
<% end %>
Routes.rb
resources :subaccounts
resources :accounts do
resources :subaccounts
end
Subaccounts controller
before_action :set_account, only: [:show, :edit, :new, :create]
before_action :set_subaccount, only: [:show, :edit, :update, :destroy]
def show
end
private
def set_account
#account ||= Account.find(params[:account_id])
end
def set_subaccount
#subaccount ||= #account.subaccounts.find(params[:id])
end
def subaccount_params
params.require(:subaccount).permit(:name, :state)
end
The issue you are facing is due to same controller action for 2 different routes. You can fix it by either adding another controller for nested route
resources :accounts do
resources :subaccounts, controller: 'accounts_subaccounts'
end
Or handle exception and check for #account (least preferred way / bad practice)
#account ||= Account.find(params[:account_id]) rescue nil
With handling with rescue you need to handle #account everywhere.
You can also trigger set_account method when params[:account_id].present? which will also work for you.

Delete/Destroy is not working within Rails

I am trying to get a delete button to work using a piece of code I have written within my tags_controller page;
def destroy
#tag = Tag.find(params[:id])
#tag.destroy
redirect_to :back, notice: 'Tag was successfully deleted!'
end
When I run from my local host, it throws an exception as shown below;
Routing Error
No route matches [DELETE] "/admin/tags/37/edit"
Rails.root: /Users/laurenwoodhams/Desktop/PROJECT/RAILS-BLOG/-t
Here is my config routes;
Rails.application.routes.draw do
get '/login' => 'admin/sessions#new'
get '/logout' => 'admin/sessions#destroy'
namespace :admin do
resources :posts
resources :tags, except: [:index]
resources :sessions, only: [:new, :create, :destroy]
resources :administrators, only: [:index, :edit, :update]
end
end
Could you please examine and explain why this may be occurring?
Thank you
DELETE is the HTTP verb (like GET or POST) which means..
To make a link to delete your tag you'll need to do something like this in your view.
<%= link_to "Delete Tag", #tag, method: "delete" %>
Then it should work properly.
P.S.
You can run bin/rake routes to see your routes.

Multiple rails resource routes split across scope

Im having some issues trying to split up a controller based on scope.
My code looks like this
scope '/admin' do
resources :pages, only: [:index, :create, :new, :edit, :update, :destroy]
end
resources :pages, only: [:show]
Ideally, Id just like to have the show page not behind the admin scope, however when I call page_path(1), it routes to /admin/pages/1, not /pages/1.
What is the easiest way to work around this issue?
Thanks
Updated with routes
pages_path GET /admin/pages(.:format) pages#index
POST /admin/pages(.:format) pages#create
new_page_path GET /admin/pages/new(.:format) pages#new
edit_page_path GET /admin/pages/:id/edit(.:format) pages#edit
page_path PATCH /admin/pages/:id(.:format) pages#update
PUT /admin/pages/:id(.:format) pages#update
DELETE /admin/pages/:id(.:format) pages#destroy
GET /pages/:id(.:format) pages#show
root_path GET / pages#main
And view:
<% #pages.each do |page| %>
<%= link_to page.title, page_path(page) %>
<% end %>
To influence route helper names, use as-parameter:
scope '/admin', as: 'admin' do
However, it makes sense to place the admin's controller in Admin namespace, so you can do this:
namespace 'admin' do
That will influence path (/admin), route helpers (admin_) and controller namespace (Admin::PagesController). A separate controller allows for easier access and layout control. Also, you can make a separate show for admins, which is nice to have.
Of course, in your forms you'll have to use constructs like form_for [:admin, #page], or form_for #page, url: admin_page_path(#page).
scope '/admin', as: 'admin' do
resources :pages, only: [:index, :create, :new, :edit, :update, :destroy]
end
resources :pages, only: [:show]
Just do the changes as above
scope module: '/admin' do
resources :pages, only: [:index, :create, :new, :edit, :update, :destroy]
end

use :only helper in routes

I have a project where user can download files. Now, i want another page for show all users. so, i add a method all_users in my addfiles_controller. I have also a view page all_users.html.erb for that. But The ploblem is with the routes.rb file . Here I want to ensure user can only use :index, :new, :create, :destroy, :all_users paths.
How can i set this :only helper in my routes.rb file, like
resources :addfiles, only: [:index, :new, :create, :destroy, :all_users]
My routes.rb file::
resources :addfiles do
collection do
get 'all_users'
end
end
you shouldn't write all_users to only, because only/except related just to standard actions index, show, new, edit, create, update, destroy which resources define by default
resources :addfiles, only: [:index, :new, :create, :destroy] do
collection do
get 'all_users'
end
end

Resources