Calling a (helper) method from a view with two arguments - ruby-on-rails

I'm having problems with calling a (helper) method in a controller from a view.
I had a helper method which i simply called in a link_to but i had problems with that and i went to look for answers to this problem and i discovered that you cannot simply call a helper method from a view that way, so i tried to follow the recommendations of another answer but it's still not working.
I'm getting this error:
No route matches [GET] "/pages/associateplace.5"
In the view (pages/associate_place_to_activity.html.erb) i have this:
<%= link_to "Choose Place", pages_associateplace_path(#activity.id, place.id), :class => 'btn btn-default btn-xs' %>
In the controller (pages_controller) i have this:
def associateplace
#activity_id = params[:activity_id]
#place_id = params[:place_id]
Activity.find(activityid).place_id=placeid
redirect_to Activity.find(activityid)
end
ยด
And in the routes.rb i have this:
put 'pages/associateplace/:activity_id/:place_id' => 'pages#associateplace', as: :associateplace

You didn't call it pages_associateplace. You called associateplace. So in your link_to you should take off the pages_ part and leave only: associateplace_path(#activity.id, place.id)
There is one more thing. You've created a PUT route. But in a link_to you need to specify that it is a PUT that you want since GET is the default. So you need to write:
<%= link_to "Choose Place", associateplace_path(#activity.id, place.id), method: :put %>

Related

Rails navigation helper method

I have two rails helper on my application helper:
def active_class(link_path)
current_page?(link_path) ? 'active' : ''
end
def active_class_white(link_path)
current_page?(link_path) ? 'active-white' : ''
end
One is for regular links the other one is for the submenus. Usually I place the link like this:
<%= link_to "Home", root_path(:anchor => 'home'), class: "nav-link #{active_class('/')}", :"data-id" => "home" %>
Now here's my problem. On my homepage I got this link where it will slide to a particular section of the site thus requires a character like #about. If I place:
<%= link_to "About", root_path(:anchor => 'about'), class: "nav-link #{active_class('/#about')}", :"data-id" => "about" %>
It's still putting the active class on the home text instead of the about (the homepage is a one page slider type).
Another thing is that for complicated url like the devise edit profile, I tried to put the ff:
<%= link_to "Edit Profile", edit_user_registration_path(current_user), class: "dropdown-item #{active_class_white('/users/edit/:id')}" %>
Placing /users/edit/:id doesn't work on this kind of URL: http://localhost:3000/users/edit.13
On this two kinds of URL my code doesn't work. Any idea how to make them work or turn this around?
Anchors are purely client-side and are not sent along with the request to the server. So, the only way to implement the first part of your question is through Javascript. You can listen for a click event on links then add the active class to the one that was clicked.
The second part of your question, where you pass in the :id segment key, can be solved by passing a route helper (along with an object) to current_page? instead of an explicit string...
class: <%= active_class(edit_user_registration_path(current_user)) %>

Change button_to attribute

Im new to ruby on rails and im currently working on a button that will change the attribute depends on the functions result. as of now i create this function that returns true or false.
def link_facebook
is_linked = FacebookLinked.link(env["omniauth.auth"])
redirect_to :controller => 'dashboard', :action => 'settings'
end
i want to change my button_to attribute(Value,class, and make it disable)
if the result retuns true.
<%= button_to 'Setup Facebook','/auth/facebook',:class=>'btn btn-default',:id=>'setup_facebook'%>
i've search ajax but i have no clue on how to start using it.
Method 1
You can do something like this
redirect_to controller: 'dashboard', action: 'settings', is_linked: is_linked
Now is linked value will passed to the settings page's url
http://localhost:3000/dashboard/settings?is_linked=true
In your view
<%= button_to 'Setup Facebook','/auth/facebook',:class=>"btn btn-default #{params[:is_linked]? '': 'disabled'}",:id=>'setup_facebook'%>
Method 2
You can have an instance variable inside your settings action in rails, Like this
def settings
#is_linked = FacebookLinked.link(env["omniauth.auth"])
...
end
So you can access in your view in a similar fashion
<%= button_to 'Setup Facebook','/auth/facebook',:class=>"btn btn-default #{#is_linked? '': 'disabled'}",:id=>'setup_facebook'%>
If the function that returns a boolean is called my_function, the default class (when true) is 'btn btn-default' and the class when the boolean is false is 'btn btn-default disabled' then you could use :
"btn btn-default #{(my_function ? '': 'disabled')}"
So overall :
<%= button_to 'Setup Facebook','/auth/facebook',:class=>"btn btn-default #{(my_function ? '': 'disabled')}",:id=>'setup_facebook'%>
Please note that you might need to use a helper to call the method from the view, as follows : helper_method :my function. Alternatively, you could create the variable in the controller (no need for helper) and pass the variable to the view.

Links and routes in Rails

Rails 4.1
Ruby 2.1.1
I have an application where I need to display a link to the controller show method. As far as I know, something like this will do it:
<%= link_to "Agent", agents_path(:id => agent.id), :class => "btn btn-warning" %>
But when Rails generates the link, it's this:
http://mydomain/agents?id=9
What I need is
http://mydomain/agents/9.
When I enter this manually, I get the agents/show view. How do I get there?
In my routes, I do not have anything special for agents. Here's the relevant code from routes.rb:
resources :agents
Which means it will generate all the routes.
rake routes output:
agents GET /agents(.:format) agents#index
POST /agents(.:format) agents#create
new_agent GET /agents/new(.:format) agents#new
edit_agent GET /agents/:id/edit(.:format) agents#edit
agent GET /agents/:id(.:format) agents#show
PATCH /agents/:id(.:format) agents#update
PUT /agents/:id(.:format) agents#update
DELETE /agents/:id(.:format) agents#destroy
and I did not get any errors generating the routes
Solution:
Apologies, but I was using agent_path, not agents_path. I did try agents_path at one point, as one of the things I tried. The problem is that I had two different views. In one, I was using the correct syntax:
<%= link_to "Agent", agent_path(agent.id), :class => "btn btn-warning" %>
and in the other I was using:
<%= link_to "Agent", agents_path(:id => agent.id), :class => "btn btn-warning" %>
I kept making changes to one of them, when the other was actually the one being rendered. I put the correct syntax in a partial and now it's working fine. The moral of the story is to always use partials, even when you think you don't need them.
You want agent_path instead of agents_path, and you don't need to specify the id. This will work just fine:
<%= link_to "Agent", agent_path(agent), :class => "btn btn-warning" %>
Whenever in doubt about what the routes are, you can always run:
bundle exec rake routes
And you'll be able to see all existing routes, and their naming.
Routing
Something you need to consider is the resourceful nature of Rails' routing:
Every time you create a resources part of the Rails routing structure, you're actually telling rails to build the above routes. This is standard practice, and means you'll be able to call article_path(article.id) as default functionality.
I believe your problem stems from this idea:
<%= link_to "Agent", agents_path(:id => agent.id), :class => "btn btn-warning" %>
--
Reference
As mentioned, you're referencing agents_path (plural), when it should be agent_path (singular).
However, you're also defining the :id parameter in the route helper itself. This can just be handled by passing the object itself to the helper:
<%= link_to article.title, article_path(article.id) %>
Or, more succinctly, Rails is able to determine the path based on the resource you pass it (hence why I mentioned resourceful routes structure):
<%= link_to article.title, article %>
This will you autimagically to the show action of the articles controller.
Simply pass your record to link_to, this will automatically generate a link to its view page
= link_to 'Agent', agent
Agent
You can do much more by using the record, example if you need a link to the edit page
= link_to 'Agent', [:edit, agent]
Agent
And so on... This technique is very useful when writing helpers that must be compatible with different models

Method Accesibility/Scope - NoMethodError

I'm working on my first rails project and I have a problem that I just cannot figure out.
I generated a Scaffold for an object named Archive
to this object I added the method processfile
when I try to link_to said method from Archives#Index I'm getting this:
undefined method `processfile' for #<Archive:0x702de78>
This is the model archive.rb
class Archive < ActiveRecord::Base
belongs_to :users
attr_accessible :file, :user_id
mount_uploader :file, FileUploader
end
This is the code on the index.html.erb (belonging to archives)
<% #archives.each do |archive| %>
<tr>
<td><%= archive.file%></td>
<td><%= User.find(archive.user_id).name %></td>
<td>
<%= link_to 'Download', archive.file_url %>
::
<%= link_to 'Show', archive %>
::
<%= link_to 'Edit', edit_archive_path(archive) %>
::
<%= link_to 'Delete', archive, confirm: 'Esta Seguro?', method: :delete %>
::
<%= link_to "Process", archive.processfile %>
</td>
</tr>
<% end %>
this is the routes.rb line:
match "archives/processfile/:id" => "archives#processfile", :as => :processfile
the processfile method defined whitin archives_controller.rb doesn't have anything on it, i just wanted to test the functionality since I'm having a hard time getting the grip of the "rails way"
archives_controler.rb
def processfile
# #archive = Archive.find(params[:id])
#do something with the archive
end
All in all, what I ultimately want to achieve is to call the processfile method on a given archive(taken from the index table) to do something with it. On the example, I watered down the method call (not passing an archive or archive.file to it) to make it run, to no avail.
I've searched a lot (on google and in here) and haven't found a clear guide that would address my problem, probably because i'm new and can't fully grasp the concepts behind rails MVC.
I've read something about methods only being accessed by same controlers but I've seen sample code when people call methods on controllers from index views without declaring them as helpers. o.0
I know it's probably a silly confusion, but I can't figure it out :(
The way you've structured your route (i.e., match "archives/processfile/:id" => "archives#processfile") means that it's expecting an archive id to be passed. You need to adjust your link_to to pass one:
# app/archives/index.html.erb
<%= link_to "Process", processfile_path(archive.id) %>
The error you're receiving is because you're trying to call an instance method called processfile on archive, but there's presumably no method by that name. The second parameter of the link_to helper is a path, not an instance method.
EDIT:
If you're looking to make your routes more RESTful (which you should do if you've created an Archive resource), you can generate all your CRUD routes by declaring resource :archives in your routes. Then, within a block, you can declare a block of member routes, all of which will route to the specified action in your archive_controller.rb and enable you to pass an archive id to the action.
# config/routes.rb
resources :archives do
member do
get 'processfile'
end
end
You added the processfile method to your ArchiveController. That does not make the method available to the Archive model. If you want the method to be available to instances of Archive models then you need to put it inside the model as an instance method.
If you what you want to do is place a route to the action processfile in your ArchiveController then you can do so by adding link_to "Process", processfile_path(id: archive.id)

link_to problem

I want to display product count in a link_to, the link_to is a part of partial displayed in application.erb.html, the problem is, I have a method in my application controller named products_on_cart which return products count, when I try this code:
<%= link_to "<%= products_on_cart%>", :controller=>"carts", :action=>"index"%>
rails give me an error:
"syntax error, unexpected '>'
...er=>"carts", :action=>"index"%>"
I don't really understand why, can somebody help me?
You can't use <%= .. %> inside of <%= .. %>.
<%= link_to products_on_cart, [:carts] %>
You're nesting ERb tags. Make sure products_on_cart() is available as a helper method, then rewrite your link_to code without nested ERb tags as follows:
<%= link_to products_on_cart(), :controller => "carts", :action => "index" %>
To make products_on_cart() a helper method, either move it to app/helpers/application.rb, or declare it as a helper in your controller:
def products_on_cart()
# method definition goes here
end
helper_method :products_on_cart
If you only need to access products_on_cart from your views and not from your controllers, putting it in app/helpers/application.rb is the preferred way to go. If you need to use it in both controllers and views, use the helper_method approach above instead.

Resources