I am calling a controller action from a view like this:
<%= link_to "cancel offer", offermethod_offer_path,
class: "btn btn-medium btn-danger pull-right" %>
The controller action deletes a record (offer). I use the params[:id] tag from the page to identify the record in the controller like this:
class OffersController < ApplicationController
def offermethod
Offer.find(params[:id]).destroy
end
.
end
However, I would like to pass an additional parameter to the offermethod. Can I pass an instance variable from the offer view, so the code would look something like
<%= link_to "cancel offer", offermethod_offer_path(#variable.id),
class: "btn btn-medium btn-danger pull-right" %>
and in the controller
def offermethod(variable)
Offer.find(variable).destroy
end
I have tried to do this but I can't pass the variable/id parameter. Get the error like 'cannot find offer with nil id'.
Can you help me with the correct way to pass the variable to the controller like this? Many thanks!
Yes, you can. However, you need to name the variable, as GET params are key/value pairs.
<%= link_to "cancel offer", offermethod_offer_path(name: #variable.id), #...
A cleaner approach would be to just add a member route to your collection, like
resources :offers do
delete :offermethod, on: :member
end
This way, you can use a simple Offer.find params[:id], like #sircapsalot may wants to say.
edit:
I don't know, but I feel like you should read the rails guides, especially the parts about REST and the HTTP verbs. If you delete/destroy a resource, you should use a DELETE type http request, as I have described the route above. However, you also need to pass the desired method to your form or your link. For a link, this would be link_to 'name', path_to_object_delete_method(object), method: :delete. The same thing counts for a form.
Related
I'm new to rails, and I'm trying to figure out how to make the [action] attribute on a form dynamic so that I can reuse the form markup.
In MVC.net it's easy as you usually specify the :controller and :action.
However in rails there's just a "simple_form_for(#my_model)" method.
If I browse to /my_models/new the action attribute is:
action = "/my_models"
But if I go to /my_models/1/edit the action attribute is:
action = "my_models/1"
What if I want to create a new action for handling POSTs of my_model AND still reuse the same _form.html.erb... how does that work?
I think it's actually rails doing this
https://github.com/rails/rails/blob/master/actionpack/lib/action_view/helpers/form_helper.rb#L230
In short it just infers the url based on the resource and whether it is new or an existing one.
SimpleForm's FormBuilder is inherited from ActionView::Helpers::FormBuilder
You can check out that code https://github.com/plataformatec/simple_form/blob/master/lib/simple_form/form_builder.rb
I guess I'm not understanding the last part. Say you wanted to use a custom action instead of the inferred ones you could just make a partial of the form elements and use that partial for all forms.
so _form.html.erb
<%= simple_form_for #my_object do |f| %>
<%= render 'form_elements' %>
<% end %>
_custom_form.html.erb
<%= simple_form_for #my_object, :url => custom_url do |f| %>
<%= render 'form_elements' %>
<% end %>
_form_elements.html.erb
form elements as usual
Inside of a rails app that I am working, I modified the link_to helper slightly:
def link_to(*args, &block)
args[1] = params[:client_id].present? ? "#{args[1]}?client_id=#{params[:client_id]}" : args[1]
super
end
I did this so I wouldn't have to add the :client_id => params[:client_id] every time I wrote a link_to inside of the app. Well, I have kind of pigeon holed myself with the following problem...
If I have this link_to:
<%= link_to "Continue to billing info", add_product_path(:product_id => #product.id), :class => 'btn' %>
Using my link_to helper creates a link, like so:
http://localhost:3001/orders/add_product?product_id=35?client_id=HT274848772
I am at a slight loss on how to modify my helper so that the link will work as normal while including the :client_id param...
You want to add your parameter to the link url, not to the link itself. Maybe you should rewrite the url_for helper, which is the helper used by all of the url helpers ( http://apidock.com/rails/ActionView/Helpers/UrlHelper/url_for )
Study -> has_many Topics -> has_many References
My Model has the following method to access references based on topic ID:
def self.rel_references(topic_id)
Reference.where(:topic_id => topic_id)
end
I am accessing the above in my controller as follows:
#references= Study.rel_references(params[:topic_id])
I need to have a form on the Study model's Show page to access the references based on the topics the user clicks. (A remote form that loads references based on the topic_id). The way I am trying to do this is:
- form_tag rel_references, :id=>"references_form", :method => 'get' do
= text_field_tag :topic_id, params[:topic_id]
= submit_tag "Get references"
However, I am not being able to access the references in my view. Please help me understand what I may be doing wrong here. I am very new to Rails so I might be missing something here. Thanks!
Removing the deprecated Style block helper - and replacing it with = in my form solved this problem for me. My form Now looks like:
= form_tag rel_references, :id=>"references_form", :method => 'get' do
= text_field_tag :topic_id, params[:topic_id]
= submit_tag "Get references"
I am currently following the Ruby on Rails Tutorial by Michael Hartl. And there is something that has been bugging me for quite some time. I looked it up but I still can't find a good answer.
Anyway, I've noticed is when you have a validation error in the signup page it renders the original signup page and changes the nav bar address. I've matched /signup to the action new, but if I use render it changes from /signup to /users (the default, because of the RESTful standard I guess).
I'll leave some lines of my code:
routes.rb
resources :users
match '/signup', :to => 'users#new'
users_controller.rb
def new
#user = User.new
#title = "Sign up"
end
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to user_path(#user)
else
#title = "Sign up"
#user.password = ""
#user.password_confirmation = ""
render 'new'
end
end
So I've tried to work around this by not using the render method but redirect_to instead but I'm having trouble using it. As it is actually sending data to the path provided, #user.errors gets overwritten by creating a new instance of the model and the flash variable cannot show the errors.
_errors.html.erb
<% if #user.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(#user.errors.count, "error") %>
prohibited the user from being saved:
</h2>
<p>There were problems with the following fields:</p>
<ul>
<% #user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
My question is: is there any way that by using render I can change the url displayed on the navbar? It's really frustrating if someone makes a mistake in the signup form, presses enter in the navbar and ends up in a totally different place.
The reason why the address changes is because you have performed a POST request to /users/ therefore the browser is doing the correct thing by displaying the different address.
There are a few of ways around this:
Store the invalid User object and redirect back to the Users.new action.
Change the URL of the Users.create action.
Use history.replaceState to change the user's address bar.
The first option keeps the controller more RESTful, however it will need use of the :session or flash to persist the data across the redirect.
The second option keeps the code simpler, but involves fiddling with the routes.rb file.
The third option relies on javascript and support for HTML5 to mess with the user's browser history.
Personally I would leave the URL as is, but if I had a client who insisted on doing this, I would go for the second option.
I'm coding the project from Ruby on Rails Tutorial: Learn Rails by Example and am having trouble with the following and unfollowing features.
I have a piece of HTML in one of my pages that looks like this:
<%= form_for current_user.relationships.build(:followed_id => #user.id),
:remote => true do |f| %>
<div><%= f.hidden_field :followed_id %></div>
<div class="actions"><%= f.submit "Follow" %></div>
<% end %>
My RelationshipsController has a create method, but it is never called. The same applies to my 'unfollow' html and corresponding destroy method. Is there something I need to add to my project to let Rails know that the relationships.build method should call the create method, or is that automatic?
Thanks in advance.
RelationshipsController has a create method
current_user.relationships.build()
Is it create or build?
Show us the controller code. Since you use "remote=> true" you probably need to change the "respond_to" code in there and create a js.erb file.