I need to call a simple controller action through my view using link_to.
In preferences > index.html.erb:
<%= link_to "My link", :controller =>
:preferences, :action => :produces_text %>
Note, I have also tried index.html.erb with this format with no luck:
<%= link_to "My link", {:controller =>
:preferences, :action => :produces_text } %>
In preferences_controller.rb:
def produces_text
puts "test"
redirect_to preferences_url
end
In routes:
resources :preferences do
member do
get 'produces_text'
end
end
"test" is not produced in the terminal when I click "My link" and I am not redirected to preferences_url either.
resources :preferences do
collection do
get 'produces_text', as: :produces_text
end
end
<%= link_to "Link", produces_text_preferences_path %>
Related
In my redmine plugin view, I've got this link:
<%= link_to "Add", :controller => "important_user", :action => "u_edit", :u_id => user.id, :p_id => #project.id, :method => :post %>
routes.rb:
resources :important_user do
collection do
post :u_edit
end
end
and controller:
class ImportantUserController < ApplicationController
def u_edit
puts 'edit!'
end
def index
puts 'ciao'
puts params[:p_id]
puts params[:u_id]
end
end
In spite of calling the expected u_edit action, clicking on the link calls the index method (I created in a second moment to avoid the AbstractController::ActionNotFound (The action 'index' could not be found for ImportantUserController) error). I've also tried using this sort of link:
<%= link_to 'Add', { :action => 'create', :u_id => user.id, :p_id => #project.id}, :method => :post %>
But it didn't work either, returning a projects?p_id=1&u_id=1 GET 404. How could I make it call the desired u_edit action?
All of the sudden I am getting this error even though it has been working for a while:
No route matches [POST] “/stories/id/invites”
Routes:
story_invites_path GET /stories/:story_id/invites(.:format) invites#index
routes.rb
resources :stories do
match '/stories/:id/invite', to: 'invite#show', via: 'get'
resources :invites , only: [:index, :show, :destroy ]
end
invites/index view
<%= form_for #invite , :url => story_invites_path do |f2| %>
<%= f2.text_field :user_id, :value => user.id , :class => 'number_field' %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
invites controller
def create
#invite = #story.invites.new(invite_params)
if #invite.save
flash[:success] = 'The user was invited!'
redirect_to(:back)
else
render :new
end
end
How do I add a post method to my invites path?
You have all sort of icky things...
This:
resources :stories do
match '/stories/:id/invite', to: 'invite#show', via: 'get'
resources :invites , only: [:index, :show, :destroy ]
end
Should be:
resources :stories do
resources :invites
end
Which will give you:
story_invites GET /stories/:story_id/invites(.:format) invites#index
POST /stories/:story_id/invites(.:format) invites#create
new_story_invite GET /stories/:story_id/invites/new(.:format) invites#new
edit_story_invite GET /stories/:story_id/invites/:id/edit(.:format) invites#edit
story_invite GET /stories/:story_id/invites/:id(.:format) invites#show
PATCH /stories/:story_id/invites/:id(.:format) invites#update
PUT /stories/:story_id/invites/:id(.:format) invites#update
DELETE /stories/:story_id/invites/:id(.:format) invites#destroy
stories GET /stories(.:format) stories#index
POST /stories(.:format) stories#create
new_story GET /stories/new(.:format) stories#new
edit_story GET /stories/:id/edit(.:format) stories#edit
story GET /stories/:id(.:format) stories#show
PATCH /stories/:id(.:format) stories#update
PUT /stories/:id(.:format) stories#update
DELETE /stories/:id(.:format) stories#destroy
If you really want to limit your invite routes, fine. But right now, you're limiting out create. Which is really why you're getting:
No route matches [POST] “/stories/id/invites”
Because you TOLD rails you didn't want a create path. Rails is dumb that way. Does what you tell it. Not what you mean.
Also, this:
match '/stories/:id/invite', to: 'invite#show', via: 'get'
Is just really full of badness and banana slugs. Please don't do that. To yourself. Or to us.
This:
<%= form_for #invite , :url => story_invites_path do |f2| %>
<%= f2.text_field :user_id, :value => user.id , :class => 'number_field' %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
probably needs to look more like this:
<%= form_for :invite, story_invites_path(story) do |f2| %>
<%= f2.hidden_field :invite, :user_id, value: #user.id %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
Use :invite instead of #invite because you're in index and you probably don't have an #invite. If you do, fine. But rails can use the symbol to infer the correct fields.
You're going to have to look up that hidden_field method, because I'm doing this from memory.
And I don't know where you're going to get story from because you're in your index method. But, you can do something like #stories = Story.all. In which case this whole block will need to wrapped in something like:
<% #stories.each do |story| %>
<%= story.name %>
<%= form_for :invite, story_invites_path(story) do |f2| %>
<%= f2.hidden_field :invite, :user_id, value: #user.id %>
<%= f2.submit 'Send', class: 'btn btn-primary' %>
<% end %>
<% end %>
Man, this makes me remember why I dislike erb. If you were doing this in HAML, it would be pretty, like unicorns and rainbows:
- #stories.each do |story|
.story-container{id: "story-id-#{story.id}"}
.story-name
= story.name
.story-invite-container
= form_for :invite, story_invites_path(story) do |f2|
= f2.hidden_field :invite, :user_id, value: #user.id
= f2.submit 'Send', class: 'btn btn-primary'
Don't you like unicorns and rainbows? Look at all those beautiful divs with ids and classes just waiting to be dressed up with your butt-kicking, mad-ninja-skills CSS (display: inline-block, anyone?). (Please tell me you're using SASS. Please?)
Now, on submit, your params are going to look something like (I'm making up the story_id and 'user_id` values):
{..., story_id: 4, invite: {user_id: 1}, ...}
I assume in invites_controller, you have something like:
class InvitesController < ActionController::Base
def index
...
#stories = Story.all
...
end
def create
#story = Story.find_by(id: params[:story_id])
#invite = #story.invites.new(invite_params)
if #invite.save
flash[:success] = 'The user was invited!'
redirect_to(:back)
else
render :new
end
end
def invite_params
params.require(:invite).permit(:user_id)
end
end
And that all ought to hang together.
For the life of me, I don't know why you redirect_to :new, but hey whatever floats your boat. (Are sure you don't want to redirect_to stories_path or maybe redirect_to story_path?)
Update your routes.rb to include create in your resources :invites, like this:
resources :stories do
match '/stories/:id/invite', to: 'invite#show', via: 'get'
resources :invites , only: [:index, :show, :destroy, :create ]
end
That change will generate this new route:
story_invites POST /stories/:story_id/invites(.:format) invites#create
I'm really really newbie in Ruby on Rails...
I'm trying to make a link to another page in my project, where it's listed the posts that belong to an escuela.
This is what I did:
In posts_controller.rb I wrote:
def postesc
#posts = Post.where(:escuela_id => params[:id])
respond_to do |format|
format.html # postesc.html.erb
format.json { render json: #posts }
end
end
In config/routes.rb I wrote:
match 'postesc' => 'posts#postesc'
In view/escuelas/listaesc.html.erb I wrote the link:
<%= link_to "Escuelas", :controller => "posts", :action => "postesc" %>
And in view/escuelas/postesc.html.erb I want to make a list of the matching posts.
But this page appears just blank, with only the layout.
Please, some help?
First make the association between post and escuela, then you can find it just by
Escuela.find(params[:id]).posts
Change your routes to -
resources :posts do
get 'postesc', :on => :collection
end
View :
<%= link_to "List posts", postesc_posts_path %>
make a change in routes.rb as
get 'postesc' => 'posts#postesc'
try...<%= link_to "Escuelas", postesc_path %>
OR
<%= link_to "Escuelas", { :controller => "posts", :action => "postesc" } %>
you're missing to add an ID for the Escuela to be selected - as you're doing in your Controller#postesc Action (as in words: where: escuela_id => params[:id]).
<%= link_to "Escuela", :controller => "posts", :action => "postesc", :id => 1 %>
but you could use the object-link method using the following syntax (by changing your routes a litte):
# in routes.rb
match 'postesc' => 'posts#postesc', on: :collection, as: 'esc_index'
# in your view
<%- for escuela in #escuelas do %>
<%= link_to "Escuela", esc_index(escueal) %>
<% end %>
I have a button_to tag in my show.html.erb file.
<%= link_to 'Click HERE to open file', #user.image.url %><br/><br/><br/>
<%= label_tag(:q, "Parse CSV File:") %><br/>
<%= button_to 'Parse CSV', {:controller => "users_controller", :action => "process" } %>
<% end %>
Then I have this added to my users_controller.rb file
# GET /users/1/process
def process
puts 'To be Implemented'
end
Im getting an error in the routing file
No route matches [POST] "/assets"
This is how my routing file looks:
resources :users
resources :listings
What should I change. Im a bit confused, woould really appreciate some help.
Please correct your route and define like this
<%= button_to 'Parse CSV', {:controller => "users", :action => "process" } %>
Then in route file
resources :users do
collection do
get: process
end
end
It will sure work
1) In view, use the controller name like 'users', not the 'users_controller' .
<%= button_to 'Parse CSV', {:controller => "users", :action => "process" } %>
2) rails define few routes by default , but for other you need to define yourself .
Declare the routes like :
resources :users do
:member => {
:process => :get
}
end
Hope that help .
I've read through the relevant Stack questions but still seem to be hitting a routing error with the following code:
Routes.rb
resources :memberships do
put :toggleon
put :toggleoff
end
Memberships_controller.rb
def toggleon
#membership = Membership.find(params[:id])
#membership.update_attributes(:active => true)
if user.id == membership_id
redirect_to root_path
else
redirect_to group
end
end
def toggleoff
#membership = Membership.find(params[:id])
#membership.update_attributes(:active => false)
if user.id == membership_id
redirect_to root_path
else
redirect_to group
end
end
Show.html.erb
<% if this_membership.active %>
<%= link_to 'Pause', this_membership, controller: :memberships, method: :toggleoff, style: 'color:#ccc' %>
<% else %>
<%= link_to 'Start', this_membership, controller: :memberships, method: :toggleon, style: 'color:green' %>
<% end %>
Error text
Started POST "/memberships/13" for 127.0.0.1 at 2011-09-27 23:35:35 +0100
ActionController::RoutingError (No route matches "/memberships/13"):
I can destroy memberships just fine but toggling the membership activity is proving tricky.
Thanks in advance!
Second attempt
<%= link_to("Pause", membership_toggle(#membership), :method => :put, :title => "This toggles it off") %>
<% else %>
<%= link_to("Toggle On", membership_toggle(#membership), :method => :put, :title => "This toggles it on") %>
and
def toggle
#membership = Membership.find(params[:id])
#membership.toggle!(active)
end
and
resources :memberships do
member do
put :toggle
end
end
now gives me this error...
undefined method `membership_toggle' for #<#<Class:0x00000102e69bc0>:0x00000102e66ec0>
Links using your routes are going to be:
link_to("Toggle On", membership_toggleon_url(membership), :method => :put, :title => "This toggles it on")
link_to("Toggle Off", membership_toggleoff_url(membership), :method => :put, :title => "This toggles it off")
You need to supply :method => :put to the link_to method given that's what you have the route as in your routes file.
Something like this can be achieved with a single action:
resources :memberships do
member do
put :toggle
end
end
Then you can make use of a single boolean field in your controller by using the Rails toggle method.
This will let you do something like:
#membership.toggle(:on)
Try setting the route as being :on => :member.
Also, there's an atomic toggle! method that does what its name implies.
Kept having issues with various techniques but eventually found this article:
http://buckybits.blogspot.com/2011/09/simple-ajax-property-toggle-in-rails-30.html
BOOM!