ActiveAdmin collection action path - ruby-on-rails

How do I set the url for a "semantic form" tag in an activeAdmin custom page partial for collection_action in my activeAdmin controller?
I have:
item.rb
ActiveAdmin.register Item, :as => "MyItems" do
menu :parent => "My", :label => "My Items"
collection_action :add_me, :method => :post do
redirect_to "/" # just for testing
end
end
custom page ActiveAdmin controller
ActiveAdmin.register_page "MyItemsCustomPage" do
content do
#items = Item.all
render "item", { :items => #items }
end
end
_item.html.erb (for custom page)
<%= semantic_form_for :item_add_me, :url => add_me_admin_items_path do |f| %>
<%= f.buttons :commit %>
<% end %>
And after going to the custom page I have the error:
undefined local variable or method `add_me_admin_items_path' for #<#<Class:0x00000006c3ff40>:0x00000005f8bd80>
btw, semantic form for admin_items_path works well for item add action.
PS. If I change the url to /admin/items/add_me and set the :method to :post, I get the routing error: No route matches [POST] "/admin/items/add_me"

Found the problem.
After removing :as => "MyItems" in item.rb:
ActiveAdmin.register Item do
All works ok.

The problem here is that ActiveAdmin.register Item, as: "MyItems" actually renames all your routes to be my_items instead of my_item in all the method names. So, in your form, instead of using add_me_admin_items_path, you could have used add_me_admin_my_items_path.

Related

Resource defines an update using PATCH but app wants POST in Rails 4

I'm trying to add edit functionality to my web app, and am having some trouble. The error page I get back when I try to complete an edit of my Request object indicates that it couldn't find the right route, but the same error page contains a list of routes which includes the route it's looking for. So I'm a bit flummoxed.
The "new" method is almost identical to this edit method and the pages are almost identical as well.
The error page begins No route matches [POST] "/requests/19/edit" and then, partway down the route listing, I see this:
requests_path GET /requests(.:format) requests#index
POST /requests(.:format) requests#create
new_request_path GET /requests/new(.:format) requests#new
edit_request_path GET /requests/:id/edit(.:format) requests#edit
request_path GET /requests/:id(.:format) requests#show
PATCH /requests/:id(.:format) requests#update
PUT /requests/:id(.:format) requests#update
DELETE /requests/:id(.:format) requests#destroy
So Rails seems to be generating a request_path which expects a PATCH, not a POST, right?
routes.rb
Rails.application.routes.draw do
root "pages#index"
resources :destinations
resources :users
resources :manifests
resources :requests
:
request.rb
class Request < ActiveRecord::Base
validates_presence_of :justification
validates_presence_of :required_by
belongs_to :user
belongs_to :manifest
belongs_to :network
has_many :uploaded_files
scope :sorted, lambda{ order("required_by") }
end
edit.html.rb
<% #page_title = "Update Request" %>
<%= link_to("<< Back to List", {:action => 'index'}, :class => 'back-link') %>
<div class="requests edit">
<h2>Update Request</h2>
<%= form_for :request, url: request_path(#request) do |f| %>
<%= render(:partial => "form", :locals => {:f => f}) %>
<div class="form-buttons">
<%= submit_tag("Update Request") %>
</div>
<% end %>
</div>
requests_controller.rb
def update
#request = Request.find(params[:id])
p = {'file' => params[:request][:uploaded_file], 'request_id' => #request.id}
uf = UploadedFile.create(p)
if #request.update_attributes(request_params)
flash[:notice] = "Request updatred succesfully"
redirect_to :action => 'show', :id => #request.id
else
render 'edit'
end
end
What have I missed?
Change
<%= form_for :request, url: request_path(#request) do |f| %>
to
<%= form_for :request, url: request_path(#request), method: :patch do |f| %>
in your edit.html.erb
form_for(as you are using it) sets POST as default HTTP verb. You need to alter it by setting method :patch which responds to the update action.
You can simplify it to just
<%= form_for #request do |f| %>
Check the APIdoc for more Info.

Simple_form path issue

Here is what I have in my view:
<%= simple_form_for :artist, :url => url_for(:action => 'upvote', :controller => 'artists'),
:method => 'post' do |f| %>
<%= f.input :choose_an_artist, :selected => "first artist", collection: [["first artist", 1], ["second artist", 2], ["third artist", 3], ["fourth artist", 4]] %>
<%= f.submit "Vote" %>
<% end %>
My ArtistsController:
def upvote
#artist = Artist.find(params[:choose_an_artist])
#artist.liked_by current_user
respond_to do |format|
format.html {redirect_to :back }
end
end
routes.rb:
resources :artists do
member do
put "like", to: "artists#upvote"
end
end
I am getting the following error:
No route matches {:action=>"upvote", :controller=>"artists"}
What could be causing this? How do I get this to work so that the user can select an artist from a collection and vote for that artist?
There are several issues in your code:
First, you defined your route as PUT and you are forcing
simple_form to produce a POST form. Change method: :post
to method: :put in your view and you should be all set.
Second, you need to define your route according to your controller and action name:
resources :artists do
member do
put :upvote
end
end
Third, you defined your route as on: :member. That means that it needs an artist_id to generate. In your setup, you need to define the route on: :collection. I'd also better use the route path method instead of url_for, it's way easier to spot this errors.
resources :artists do
collection do
put :upvote
end
end
And change the url_for part for update_artists_path (if that's the correct route from rake routes).
Another issue not related to your question: :choose_an_artist is not an attribute defined in Artist model. This will cause another error when rendering the form.
I'd either rename that per the actual attribute name you are selecting, :id and change the controller accordingly (my choice), or change the form helper from f.input to a non-model related select_tag and keep the names as they are.

Rails route error switch local

I'm setting my new Rails website in more than one language, and I'm having problems with the routes. I'm following the instruction of the book 'Agile web development with Rails 4'.
The browser print me this error but I can see that routes are created correctly, so:
What am I doing wrong? (At the end of this message I'll attach all my routes)
No route matches [POST] "/en/home"
When I try putting the routes directly in the browser ("localhost:3000/en" OR "localhost:3000/es") everything works OK. The error prints only when I change my language's switcher. That's why I think the routes are correctly set, and I think is a problem of my switcher or the controller...?
This is the code in the application.html.rb (basically a switcher between languages):
<%= form_tag home_path, class: 'locale' do %>
<%= select_tag 'set_locale',
options_for_select(LANGUAGES, I18n.locale.to_s),
onchange: 'this.form.submit()' %>
<%= submit_tag 'submit' %>
<%= javascript_tag "$('.locale input').hide()" %>
<% end %>
This is the configuration of my routes.rb file:
Group::Application.routes.draw do
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
scope '(:locale)' do
resources :posts
resources :contacts
root "posts#home"
get "/home" => "posts#home"
get "/contact" => "contacts#new"
# static pages
get "/investment" => "contents#investment"
get "/partner-with-us" => "contents#partner", as: "partner"
get "/our-companies" => "contents#companies", as: "companies"
get "/site-map" => "contents#sitemap", as: "sitemap"
get "/terms-and-conditions" => "contents#terms", as: "terms"
get "/privacy" => "contents#privacy"
end
end
This is a file created in /config/initializers/i18n.rb:
#encoding: utf-8
I18n.default_locale = :en
LANGUAGES = [
['English', 'en'],
["EspaƱol".html_safe, 'es']
]
And finally, this is the code for my posts_controller.rb, because here is where I create an action "home" in order to put the last post in the home page:
class PostsController < ApplicationController
def index
#posts = Post.all.order("created_at desc")
end
def show
#post = Post.find(params[:id])
end
def home
if params[:set_locale]
redirect_to home_url(locale: params[:set_locale])
else
#posts = Post.all.order("created_at desc")
end
end
end
try to add :method => :get to your form, like this
<%= form_tag home_path, class: 'locale', :method => :get do %>

Resource Route linked to incorrect action

I am just starting out with rails and have run into some difficulties. I am trying to create a basic form that will add a new entry to the "Main" database. When I submit the form, instead of running "new" it appears to be trying to run "update", which according to the documentation should be called by /photos/:id
There error I am getting on the browser is
Unknown action
The action 'update' could not be found for AdminController
Controller:
class AdminController < ApplicationController
def index
#post = Main.create
end
def new
end
end
index.erb.html:
<%= form_for #post, :url => { :action => "new" }, :html => {:class => "nifty_form"} do |f| %>
<%= f.text_field :title %>
<%= f.text_area :entry, :size => "60x12" %>
<%= f.submit "New" %>
<% end %>
Routes:
Tasks::Application.routes.draw do
root :to => "Main#index"
resources :main
resources :admin
In Rails new is supposed to show the form to enter a new item.
edit is for showing the form to edit an existing item.
The form data is then POSTed to mains_url if it's a new item or PUT if its an exitsing item.
POST is routed to the create action.
PUT is routed to the update action.
So, to create an item, you have to implement create, to update it, you have to implement update
see
rake routes

Rails: form for different controller

I'm developing a rails app with a landingpage. On the landingpage, the user can sign up for the app. For login, there is an extra view with an extra controller.
It looks like this:
views/landinpage/index.html --> sign up form
views/login/index.html --> login form
but I only want to have one controller
controllers/login_controller --> create new user from sign up form & check login data
so I have to get a connection between the landingpage view and the login_controller.
This is my attempt:
<%= form_for #login, :url => { :controller => "login_controller", :action => "create" }, :html => {:method => :post} do |f| %>
but it throws a route error:
No route matches {:controller=>"login_controller", :action=>"create"}
I already defined login resources in routes.rb, but it seems that the problem is elsewhere?
resources :logins
any ideas?
try this
class LoginsController < ApplicationController
def new
...
end
def create
...
end
...
end
in your route.rb file write
match '/login/create' => 'logins#create', :as => :create_login
or
resources :logins
in your console - write - rake routes and check your routes
then
<%= form_for #login, :url => create_login_path(#login) do |f| %>
I think your code should look like this:
<%= form_for #login, :url => { :controller => "login", :action => "create" }, :html => {:method => :post} do |f| %>
can't test this right now, but I believe the _controller part is not required.
Update:
Another thing that I'm using a lot and that works:
<%= form_for #login, :url => create_login_path(#login), :html => {:method => :post} do |f| %>
You may have to fix the create_login_path part to match your application's routes but that's how I usually define these views.
Try this
class LoginsController < ApplicationController
def new
...
end
def create
...
end
...
end
in your routes.rb file
resources :logins do
collection do
post :create
end
end
and in your views
<%= form_for #login, :url => create_login_path(#login) do |f| %>>
you can see the html form action part, you can see!
your config/routes has
resources :posts
namespace :admin do
resources :posts
end

Resources