link_to problem - ruby-on-rails

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.

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)) %>

Calling a (helper) method from a view with two arguments

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 %>

How do I refactor a conditional statement?

I'm on Rails 4 and Im using devise for user management. I have a simple conditional statement in a show view like this
<% if user_signed_in? %>
<%= link_to "Checkout", user_cart_path(current_user,#cart), method: :patch %>
<% else %>
<%= link_to "Checkout", signin_path %>
<% end %>
I want to clean up my view and add make the conditional a method.
I have tried adding the method
def checkout_link(current_user)
if user_signed_in?
link_to "Checkout", user_cart_path(current_user, self), method: :patch
else
link_to "Checkout", signin_path
end
end
to my cart model, and replaced the conditional in my show cart view to
<%= #cart.checkout_link(current_user) %>
When I load the cart show page, I get an error
undefined method `user_signed_in?' for #<Cart:0x007fd015525228>
What am I doing wrong?
Thanks.
The thing you are doing wrong is concerning your model with the view. This should not be done.
You should place the checkout_link in a view helper method. This will clean up your view, and keep the model only concerned about the data it contains.
Though, in this case, I would just have a single link that leads to the checkout, and if the user is not signed in, have a before_filter redirect them to sign in.
You have two options, you can either add to the view helper or use a decorator.
If you add the method to the view, it would look something like this:
def checkout_link(cart)
if user_signed_in?
link_to "Checkout", user_cart_path(current_user,cart), method: :patch
else
link_to "Checkout", signin_path
end
end
"The decorator wraps the model, and deals only with presentational concerns. In the controller, you decorate the article before handing it off to the view."1 If you would like to use a decorator, check out Ryan Bates' Railscast on them: using an existing gem or creating a decorator from scratch.
1 Quoted from the Draper gem's README. https://github.com/drapergem/draper
You're almost there. You want your checkout_link method to be a "helper method" in a helper file, not in your model file. So, create a file named app/helpers/carts_helper.rb and move your checkout_link method there. Methods in helper files are available to views and controllers.
When I was just learning my way around Rails, I would do:
rails generate scaffold Dummy
specifically to see what files it generated, including helper files. This might be a good place to start.

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)

rails partial or helper

I'm programming a large application using Rails 3 and I keep creating search forms like so:
= form_tag search_companies_path, :method => "get" do
= label_tag :search
= text_field_tag :search
= submit_tag "Search"
Should this be put into a Helper method or Partial?
I tried to get it working through a Helper:
module ApplicationHelper
def search_form(path)
form_tag path, :method => "get" do
label_tag :search
text_field_tag :search
submit_tag "Search"
end
end
end
This creates a form with a button, am I on the right track here?
Putting it into a helper - in my humble opinion - is not a good practice since helpers are supposed to take code out of views, not to take views excerpts - which is the case for partials.
I would definitely use partials for this function!
If you want to share a partial between different parts of your application, you can store them in a folder called "shared" (or whatever name you like) and insert them into the view by calling render :partial => '/shared/name_of_the_partial'.
i think that partial is a more manutenible way to accomplish that task, because it's easier updating the code and also because you should save memory because the application helper is include in all helper.
You can create that partial on shared, naming it _search.html.erb.

Resources