Change a route to a controller - ruby-on-rails-3

I have a basic app and I'm trying to destroy a record in a table called meeting_participants based on both the meeting_id and participant_id (which are columns in meeting_participants).
I have changed the destroy action in my meeting_participants_controller, to accept the meeting_id and participant_id and then delete the appropriate record.
def destroy
session[:return_to] = request.referer
#meeting_participant = MeetingParticipant.find_by_meeting_id_and_participant_id(params[:meeting_id], params[:participant_id])
#meeting_participant.destroy
redirect_to session[:return_to]
end
I have a button in a view I would like to use to call the meeting_participants#destroy controller, using the following code.
<table>
<% #participants.each do |participant| %>
<tr>
<td><%= participant.name %></dt>
<td>
<% participant.meetings.each do |meeting| %>
<%= meeting.name %>
<%= button_to( "Remove Meeting",
{:controller => "meeting_participants",
:action => "destroy",
:meeting_id => meeting.id,
:participant_id => participant.id },
:method => :delete,
:confirm => "Are you sure?") %>
<br/>
<% end %>
</td>
</tr>
<% end %>
</table>
I think that I am successfully sending the correct participant_id and meeting_id parameters to the controller but I am getting a "No route matches" error because my route for meeting_participants#destroy is expecting a single :id parameter instead. rake routes gives...
meeting_participant DELETE /meeting_participants/:id(.:format) meeting_participants#destroy
Does anyone know of a way to change my route to expect the two new parameters instead of id? Or maybe there is a better approach altogether. I find routes very confusing.
Thanks.
My routes.rb files is...
MyApp::Application.routes.draw do
resources :meeting_participants
resources :participants
resources :meetings
end

I'd probably create a route to handle that request. Maybe something like:
match '/delete_meeting_participants/meeting/:meeting_id/participant/:participant_id' => 'meeting_participants#delete_meeting_participants', :as => 'delete_meeting_participants'
Then, in your controller you would have an action called delete_meeting_participants that has the same logic currently in your destroy action. Obviously you would have to update your button_to with the name of the newly created action.

Related

Delete action and create action for Rails version 2.3.2

Just now I am starting to study Ruby on Rails.
ruby version=1.8.7
rails version =2.3.2
I created delete and create new user action but present some errors,
the errors are:
uninitialized constant User::Id
Extracted source (around line #19):
16: <td><%= user.fname %></td>
17: <td><%= user.lname %></td>
18: <td><%= user.dob %></td>
19: <td><%= button_to "delete", :url => {:controller => :users,:action => 'destroy',:id =>user.id}, :method => :delete %></td>
20: </tr>
21: <% end %>
22: </table>
My MySQL database table is:
id fname lname dob
1 kamal vimal 2012.02.12
2 rahu sharmi 2012.05.26
3 mithun kavi 2012.03.07
Class user:
class User < ActiveRecord::Base
set_primary_key :id
has_one :id
end
My controller is:
class UsersController < ApplicationController
def index
#users=User.all
end
def destroy
# User.primary_key='id'
#users=User.find(:id)
#users.destroy
flash[:notice] = "You have successfully Delete Recode"
end
def new
#users=User.new
end
def create
#users=User.new(params[:users])
if #user.save
redirect_to_users_path
flash[:notice] = "Your record is created!"
else
render :action => "index"
end
end
end
My view is:
<% #users.each do |user| %>
<%= button_to "delete", :url => {:controller => :users,:action => 'destroy',:id =>user.id}, :method => :delete %>
<% end %>
Anyone can help me?
I see a couple of misunderstanding.
Users Controller
If you look the delete method in the controller
def destroy
#users=User.find(:id)
[...]
You are passing a symbol to the find function instead of the id from the delete request. You can get the id by using params[:id], as you have done with the create function.
def destroy
#users=User.find(params[:id])
[...]
The following are only suggestions.
I will also change the instance variable name from #users to #user here and in the new and the create method, since you are getting/build a single user.
If your routes.rb is set like
ActionController::Routing::Routes.draw do |map|
map.resources :users
end
you don't need to specify the url specifying the controller and the action in the button_to helper, but you can use the path helpers
button_to "delete", user_path(user), :method => :delete
User model
You can remove both the statements.
You should user set_primary_key only if the primary key in the table differs from the default 'id'.
The association is misused.
With the has_one method you are telling Rails the User model is related with the model 'id' through a 1:1 relation which, I suppose, is not what you want.
Final Thoughts
Read carefully the Ruby on Rails guide if you did not, it's a good starting point.
In addition, you are using a really old version of Rails and Ruby, which are not supported anymore. If there aren't any specific reason, like working on a legacy project, I suggest you to study a more recent version like Rails 4 on ruby 2.2.

Rails: No route matches [PUT] "/blog/2"

I am creating blog application in rails. I have a common form for creating and updating blog.
This is view of edit and new.html.erb
<%= render :partial => "form"%>
This is view of _form.html.erb blog:
<%= form_for #blog do |f| %>
<%= f.text_field :title, :placeholder => "Title" %><br>
<%= f.cktext_area :article, :placeholder => "Content", :ckeditor => {:toolbar => "MyToolbar"} %>
<%= f.submit %>
<% end %>
My blog is creating successfully but I am getting error on update action. This is my edit and update action in blog controller:
def edit
#blog = Blog.find_by_slug(params[:id])
end
def update
#blog = Blog.find(params[:id]) || not_found
#blog.update_attributes(params[:blog])
redirect_to "/blogs/#{#blog.slug}"
end
When I open form from edit view, and click on update button, it throws error:
No route matches [PUT] "/blog/2"
My routes.rb is:
resources :blogs
get 'blog', to: 'blogs#index'
get '/blog/:id', to: 'blogs#show', as: 'blog'
I am not getting where it is going wrong. I tried to add "url: blogs_path" in form_for, it removes the error but doesn't save the edit changes.
Can anybody help me where I am going wrong here?
Thank you.
Okay. I dont understand why you want to go against conventions. Anyway, using form_for resource would automatically generate action URL as a PUT to /resources/:id if its an update operation.
So to override this you need to do two things.
update your routes to support this:
Add this line to your routes file:
put 'blog/:id' => 'blogs#update', :as => 'update_blog'
It is important that you put this line above your 'resources :blogs` call.
2 . specify the URL to which the form should submit:
You will need to create the form tag like this:
<%= form_for #blog, :url => update_blog_path(#blog) do |f| %>
Try this and let us know.

No route matches [POST] "/contacts/1"

app/view/contact/show.html/erb
<%= form_for(#contact) do |f| %>
<p id="notice"><%= notice %></p>
<p>
<b>Firstname:</b>
<%= #contact.firstname %>
</p>
<p>
<b>Lastname:</b>
<%= #contact.lastname %>
</p>
<p>
<b>Email:</b>
<%= #contact.email %>
</p>
<p>
<b>Mobilephone:</b>
<%= #contact.mobilephone %>
</p>
<% end %>
<%= link_to 'Edit', edit_contact_path(#contact) %> |
<%= link_to 'List', contacts_path %>
in my view/contact/index.html.erb i have a button
<%= button_to 'show', contact %>
in my contacts_controller.rb i just use automatic setting like:
def show
#contact = Contact.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #contact }
end
end
in my routes file
match '/contacts/:id/edit', :controller => 'contacts', :action => 'edit'
match '/contacts/contact_:id/show', :controller => 'contacts', :action => 'show'
resources :contacts
resources :connections
resources :addresses
root :to => 'contacts#index'
and after running rake routes i got
/contacts/:id/edit(.:format) contacts#edit
/contacts/:id/show(.:format) contacts#show
contacts GET /contacts(.:format) contacts#index
POST /contacts(.:format) contacts#create
new_contact GET /contacts/new(.:format) contacts#new
edit_contact GET /contacts/:id/edit(.:format) contacts#edit
contact GET /contacts/:id(.:format) contacts#show
PUT /contacts/:id(.:format) contacts#update
DELETE /contacts/:id(.:format) contacts#destroy
connections GET /connections(.:format) connections#index
POST /connections(.:format) connections#create
new_connection GET /connections/new(.:format) connections#new
edit_connection GET /connections/:id/edit(.:format) connections#edit
connection GET /connections/:id(.:format) connections#show
PUT /connections/:id(.:format) connections#update
DELETE /connections/:id(.:format) connections#destroy
addresses GET /addresses(.:format) addresses#index
POST /addresses(.:format) addresses#create
new_address GET /addresses/new(.:format) addresses#new
edit_address GET /addresses/:id/edit(.:format) addresses#edit
address GET /addresses/:id(.:format) addresses#show
PUT /addresses/:id(.:format) addresses#update
DELETE /addresses/:id(.:format) addresses#destroy
root / contacts#index
And when i click the button 'show' i got Routes Error No route matches [POST] "/contacts/1" Could somebody help me checking what mistake i have maken,please? Thank you very much for helping.
Maybe it's easier if you use the standard routing offered by resources contacts - then you could simply use <%= link_to 'show', contact_path(contact) %>
Also, the button should perform a GET request, not a POST since that route is not defined.
If I were you I would remove the first two custom routes you declared and just rely on the resources :contacts method instead. This in combination with a GET request should fix your problem.

Update don´t get the value of local when doing an update using i18n

I have tried to use i18n internationalization in my application.
It works very well when I do a Show (index), Create, and Edit. My problem is when I do an update.
When I press the update button I don´t get the :locale value back
Normaly I get these values back.
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
level: '5_3'
menu_item: '5'
menu_level: '5_3_1'
action: index
controller: communication_mails
locale: dk
The URL looks like:
localhost:3000/dk/communication_mails
When I press the Edit button I get these values back. (The “Button” is a link). Locale is still ok.
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
level: '5_3'
menu_item: '5'
menu_level: '5_3_2'
action: edit
controller: communication_mails
locale: dk
id: '2'
The URL now looks like:
localhost:3000/dk/communication_mails/2/edit
My problem is when I now press the “Update” button under the form field the redirection don´t get the value of locale back... It instead uses the ID.
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
level: '5_3'
menu_item: '5'
menu_level: '5_3_1'
action: index
controller: communication_mails
locale: '2'
The URL now looks like:
localhost:3000/2/communication_mails
My route looks something likes this:
scope "/:locale" do
resources :communication_mails
end
resources :communication_mails do
collection do
get 'communication_mails'
post 'communication_mails'
put 'communication_mails'
end
end
root :to => redirect("/dk/tests/")
match '/communication_mails/:id/edit(.:format)', :to => 'communication_mails#edit'
match '/communication_mails/:id/', :to => 'communication_mails#index'
match '/communication_mails', :to => 'communication_mails#index'
My Controller is made like this.
def edit
#communication_mail = CommunicationMail.find(params[:id])
#show_calendars = Calendar.where(:calendar_priority => '1')
#show_email_text = CommunicationMail.find_by_sql("SELECT calendars.id,
calendar_name, communication_mail_headline, communication_mail_text
FROM calendars LEFT OUTER JOIN communication_mails
ON communication_mails.communication_mail_calendar_id = calendars.id
WHERE communication_mails.communication_mail_priority = '1'")
end
def update
#communication_mail = CommunicationMail.update(params[:id], params[:communication_mail])
#show_calendars = Calendar.where(:calendar_priority => '1')
#show_email_text = CommunicationMail.find_by_sql("SELECT calendars.id,
calendar_name, communication_mail_headline, communication_mail_text
FROM calendars LEFT OUTER JOIN communication_mails
ON communication_mails.communication_mail_calendar_id = calendars.id
WHERE communication_mails.communication_mail_priority = '1'")
if #communication_mail
redirect_to communication_mails_path(:menu_item => '5', :level => '5_3', :menu_level => '5_3_1'),
:notice => 'Opdateringen af E-mail tekst lykkedes'
else
redirect_to communication_mails_path(:menu_item => '5', :level => '5_3', :menu_level => '5_3_1'),
:notice => 'Opdateringen af E-mail tekst lykkedes IKKE'
end
end
I have solved many questions by looking through these pages. But I can´t find an answer to this one.
I hope some one can help me out. Thanks in in advance.
UPDATE
My routes looks like this:
GET /:locale/communication_mails/communication_mails(.:format) communication_mails#communication_mails
POST /:locale/communication_mails/communication_mails(.:format) communication_mails#communication_mails
PUT /:locale/communication_mails/communication_mails(.:format) communication_mails#communication_mails
GET /:locale/communication_mails(.:format) communication_mails#index
POST /:locale/communication_mails(.:format) communication_mails#create
GET /:locale/communication_mails/new(.:format) communication_mails#new
GET /:locale/communication_mails/:id/edit(.:format) communication_mails#edit
GET /:locale/communication_mails/:id(.:format) communication_mails#show
PUT /:locale/communication_mails/:id(.:format) communication_mails#update
DELETE /:locale/communication_mails/:id(.:format) communication_mails#destroy
The form I use to send and update the data
<%= form_for(#communication_mail) do |f| %>
<table class="toggle_header2">
<tr>
<td class="nobr width50px font_size13 font_weight_bold color03 border_left">
<%= t('forms.calendar') %>
</td>
<td class="color03 border_right">
<%= collection_select(:communication_mail,
:communication_mail_calendar_id,
#show_calendars,
:id,
:calendar_name,
{:include_blank => true },
{:prompt => true})
%>
</td>
</tr>
<tr>
<td class="nobr width50px font_size13 font_weight_bold color03 border_left">
<%= t('forms.headline') %>
</td>
<td class="color03 border_right">
<%= f.text_field :communication_mail_headline, :class => 'width350px' %>
</td>
</tr>
<tr>
<td class="nobr align_top font_size13 font_weight_bold color03 border_left">
<%= t('forms.text') %>
</td>
<td class="color03 border_right">
<%= f.text_area :communication_mail_text, :class => 'width350px' %>
</td>
</tr>
<tr>
<td class="color03 border_left">
<%= f.hidden_field :communication_mail_priority, :value => '1' %>
</td>
<td class="color03 border_right">
<% if action_name == 'edit' || action_name == 'update' %>
<%= f.submit t('buttons.update') %>
<% else %>
<%= f.submit t('buttons.insert') %>
<% end %>
</td>
</tr>
</table>
<% end %>
If you pick your :locale value from params, you have incorrect approach in your routing.
Update: be sure you are passing :locale value to your routing helpers on update action.
This code will generate routes with scope only for index, show, new, create, edit, update, destroy actions.
scope "/:locale" do
resources :communication_mails
end
This code will add additional routes to :communication_mails, but without scope.
resources :communication_mails do
collection do
get 'communication_mails'
post 'communication_mails'
put 'communication_mails'
end
end
Solution is to combine. You have to define :scope for all of your :communication_mails actions.
scope "/:locale" do
resources :communication_mails do
collection do
get 'communication_mails'
post 'communication_mails'
put 'communication_mails'
end
end
end
Please read documentation about routing (it is basics): http://guides.rubyonrails.org/routing.html

Rails passing local parameters through link_to into js then load in partial

I am trying to pass along a local variable to a partial using link_to. I have tried many different things, but it doesn't seem to work. The js file loads the partial fine, it just doesn't have the locals. This is what I have, thanks for any direction!
_health.html.erb (this is a partial on index.html of Contacts model)
<% #comments = Comment.find_all_by_api(#api) %>
<%= link_to 'Read Comments', comments_path(:comments => #comments), :action => 'comments', :remote => true %>
comments.js.erb
$("#comments").html("<%= escape_javascript(render(:partial => 'comment', :locals => {:comments => :comments})) %>");
comment.html.erb
<% unless #comments.blank? %>
<% #comments.each do |c| %>
<%= c %><br />
<% end %>
<% end %>
contacts_controller.rb
def comments
respond_to do | format |
format.js {render :layout => false}
end
end
The partial does not know about the comments because you never set them. The comments action in the controller needs to look like this:
def comments
#comments = Comment.find(params[:id])
respond_to do | format |
(replace params[:id] with the appropriate parameter from your route)
You're doing an AJAX request and since http is stateless, the comments action does not know anything about any previous requests - which means that the comments from _health.html.erb have ceased to exist for the comments action in the controller.