undefined method `refreshProfile_affinity_path' for #<#<Class:0x8daee70>:0x8dbdc30> - ruby

I'm getting the error in the title. I am not sure how exactly to write the routes, controller, and index.
I am trying to create a 'Refresh' button in an index.html.erb view shown below:
...
<td><%= link_to 'Refresh', refreshProfile_affinity_path(a), method: :put %></td>
...
It is using this route in routes.rb:
resources :affinities
put 'affinities/refreshProfile/:id' => 'affinities#refreshProfile'
It is trying to access the following method in the affinities_controller.erb:
...
def refreshProfile
#affinity = Affinity.find(params[:id])
new_profile_affinity = User.find(#affinity.user_A_id).profile_affinity_with(User.find(#affinity.user_B_id))
if #affinity.update_attributes(:integer, new_profile_affinity)
redirect_to #affinity
end
end
...
What could be wrong? Any help is greatly appreciated!

You need to add an as: to your route, this is what specifies the prefix for the helper method and is why you're currently getting an undefined method error e.g.
put 'affinities/refreshProfile/:id' => 'affinities#refreshProfile',
as: 'refreshProfile_affinity'
refreshProfile_affinity_path would then work, or you could give it a shorter, snappier name e.g. as: 'refreshProfile' and then use refreshProfile_path.

Related

Hanami, show 'post' controller/view

I don't understand Hanami, I've created Message model, and I want to pull from DB message by params[:id]. The way we do it in Rails #message = Message.find(params[:id].
I read documentation, and what I did after. My Controller (for show):
def call(params)
#message = MessageRepository.find(params[:id])
end
And my erb:
<%= #message.title %>
But it gives me error:
NoMethodError: undefined method `title' for nil:NilClass
What I did wrong?
At the controller call expose :message, then you can use it in the view or in the template as local variable (without the #).

form_tag calling an instance of a class on the controller

I am trying to use a form_tag on a Rails application that, when submitted, call an instance of a class on the controller.
View
form_tag '/order', method: :get
select_tag 'type', options_for_select(#options_for_type, #type)
text_field_tag 'numbers', nil, placeholder: "100"
submit_tag "Get Info"
controller
def order
#order = Order.new(params_here).fetch_info
#type = params[:type] || "type1"
#options_for_type = [["type1", "type1"], ["type2", "type2"]]
...
end
This class sends some API requests (JSON).
Now problem is, I am getting an error from the API that some parameters are missing, which is expected since I haven't submitted the form with all the params, but it seems the class is called automatically when the page is loaded. I would have expected the class to be called only when the submit button is pressed?
Can you make the form_tag sort of a block? Like:
form_tag '/order', method: :get do
# All form elements
end
Maybe displaying your route here can also help.

Rails remote delete and update view through Ajax

In the past, whenever I wanted to update a part of my view through Ajax, I've done the following:
create a partial out of the part I want to update and give it a unique ID, say #tracks
create a special action in the controller for that Ajax call, say remove_track that updates all the values, etc. and add format.js
create a new JS file with the same name as the action so Rails calls it automatically remove_track.js.erb which contains something like: $('#tracks').html("<%=j render 'cds/show_tracks' %>");
set remote: true in the link that calls this action.
All this is fine, but now I am trying to delete and update a common index view using the regular destroy method for flexibility, meaning I can call this method either through Ajax or normally. I figured it's such a common thing to do that there has to be a better way than all of the above.
I can get the destroy method to call my destroy.js.erb file by simply putting this into the controller:
format.js { layout: false }
and of course setting remote: true on the link.
what I cannot do is get the view to refresh. The table I want to refresh is encased in a div with a unique ID, but since it's not a partial, it refuses to refresh the content. Maybe I'm missing something.
Am I doomed to have to create a partial and refresh it with the method above or is there a more magical way of doing it (other than using Turbolinks)?
Thanks.
PS
Also, I just noticed this has the added disadvantage that I cannot pass the rest of the params to the destroy method since it only passes the object ID to destroy using the regular CRUD routes. If I try to use platform(action: destroy) or platform(method: delete) I get an error:
No route matches {:action=>"destroy", :controller=>"platforms"}
Which means I have to create a new route if I want to pass those parameters...
Yet another disadvantage to all this is that I'm repeading all the logic for searches and sorting that I have in the index method again in the destroy method. I am certain this is definitely not the way to do it.
Thanks to this page I found the proper way to do it. So simple and effective.
http://carmennorahgraydean.blogspot.com.es/2012/10/rails-328-ajax-super-basic-example.html
Update your destroy line in index.html.erb:
<%= link_to 'Destroy', pony, method: :delete, data: { confirm:
'Are you sure?' }, :remote => true, :class => 'delete_pony' %>
Create a file, destroy.js.erb, put it next to your other .erb files
(under app/views/ponies). It should look like this:
$('.delete_pony').bind('ajax:success', function() {
$(this).closest('tr').fadeOut();
});
Add format.js { render :layout => false } to your controller:
respond_to do |format|
format.html { redirect_to ponies_url }
format.json { head :no_content }
format.js { render :layout => false }
end
Hope this helps someone else.

Undefined method 'to_i' for :Symbol

RoR novice here, appreciate any help.
I have the following error:
undefined method `to_i' for :funding_level:Symbol
Am trying to pass both funding_level and investment_id parameters from link_to into the new method in my controller.
From my understanding, the 100 value gets passed as a Symbol and not an Object, causing problems when I then try to assign it to #funding_level, an integer variable.
Thanks!
HTML:
<div id="investment-status">
<%= link_to "$100", new_project_funding_path(funding_level: 100,investment_id: #project.id), class: 'btn' %>
</div>
Controller:
def new
#investment = Project.find(params[:investment_id])
#funding_offered = :funding_level
#project_funding = current_user.project_fundings.new(investment: #investment, funding_offered: #funding_offered)
end
Shouldn't be this instead ?
#funding_offered = params[:funding_level]

No route matches [POST] "/story/new" after submitting form

I've just started "Build Your Own Ruby on Rails" and I have had to use Google a lot, as the book seems to have a bunch of places where the code just doesn't work. This time, I couldn't find an answer. Okay, so here's the deal. I have a form that looks like this:
new.html.erb:
<%= form_for :story do |f| %>
<p>
name:<br />
<%= f.text_field :name %>
</p>
<p>
link: <br />
<%= f.text_field :link %>
</p>
<p>
<%= submit_tag %>
</p>
<% end %>
It shows up fine when I go to localhost:3000/story/new. The thing is, when I try to type stuff into the form and press "submit," I get this error:
Routing Error
No route matches [POST] "/story/new"
My routes.rb looks like this:
FirstApp::Application.routes.draw do
resources :story
story_controller looks like this:
def new
#story = Story.new(params[:story])
if request.post?
#story.save
end
end
The story_controller stuff for new is straight out of the book. I thought I might have had a solution here, but no dice. Any help would be greatly appreciated.
I'm guessing you meant (note the at sign):
<%= form_for #story do |f| %>
That'll probably take care of your routing issue, but as John mentions, your controller action is a bit off, too. The new action should only load a dummy model and display the new.html.erb page - the saving should take place in a separate action, called create.
Hope this helps!
Edit: Minimal controller code:
class StoriesController < ApplicationController
def new
#Make a dummy story so any default fields are filled correctly...
#story = Story.new
end
def create
#story = Story.new(params[:story])
if(#story.save)
#Saved successfully; go to the index (or wherever)...
redirect_to :action => :index
else
#Validation failed; show the "new" form again...
render :action => :new
end
end
end
First off, Rails is relies on convention over configuration when using singular vs plural names. If you want to follow convention, you have to change the line in your routes.rb to resources :stories, which would generate following routes:
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
PUT /stories/:id(.:format) stories#update
DELETE /stories/:id(.:format) stories#destroy
Note, that in this case you would have to rename your controller to StoriesController. However, your routes.rb has resources :story, which generates following routes:
story_index GET /story(.:format) story#index
POST /story(.:format) story#create
new_story GET /story/new(.:format) story#new
edit_story GET /story/:id/edit(.:format) story#edit
story GET /story/:id(.:format) story#show
PUT /story/:id(.:format) story#update
DELETE /story/:id(.:format) story#destroy
As you can see, indeed, there is no route for POST /story/new. I guess, the error that you are getting is triggered by following code in your controller:
if request.post?
#story.save
end
It is quite wrong, because you trying to check for POST request inside the action that is routed to by GET. Just remove this code from your new action and add create action to your StoryController like this:
def create
#story = params[:story]
if #story.save
redirect_to #story, notice: "Story created"
else
render action: "new"
end
end
This should resolve your issue for now. But I strongly recommend using plural stories for your resources, since it will be back to haunt you again.
This is the part that you (and me) have missed from the guide:
There's one problem with this form though. If you inspect the HTML
that is generated, by viewing the source of the page, you will see
that the action attribute for the form is pointing at /articles/new.
This is a problem because this route goes to the very page that you're
on right at the moment, and that route should only be used to display
the form for a new article.
The form needs to use a different URL in order to go somewhere else.
This can be done quite simply with the :url option of form_for.
Typically in Rails, the action that is used for new form submissions
like this is called "create", and so the form should be pointed to
that action.
Edit the form_for line inside app/views/articles/new.html.erb to look like this:
<%= form_for :story, url: stories_path do |f| %>

Resources