undefined method `stringify_keys' for "/posts/7/up-vote":String - ruby-on-rails

I am getting this error:
NoMethodError - undefined method `stringify_keys' for "/posts/7/up-vote":String:
This is my code:
<% if policy(Vote.new).create? %>
<div class="vote-arrows pull-left">
<div if vote = current_user.vote(post) %>
<%= link_to [post, Vote.new], post_up_vote_path(post), class: 'btn btn-primary', method: :up_vote do %>
<i class = "glyphicon glyphicon-chevron-up #{(current_user.voted(post) && current_user.voted(post).up_vote?) ? 'voted' : '' }" ></i> Upvote
<strong><%= post.points %></strong>
<% end %>
<% else %>
<%= link_to [post, vote], post_down_vote_path(post), class: 'btn btn-danger', method: :down_vote do %> <i class = "glyphicon glyphicon-chevron-down #{(current_user.voted(post) && current_user.voted(post).down_vote?) ? 'voted' : '' }"></i>;nbsp; Downvote
<% end %>
</div>
<% end %>
I am getting the error on this line:
<%= link_to [post, Vote.new], post_up_vote_path(post), class: 'btn btn-primary', method: :up_vote do %>
<i class = "glyphicon glyphicon-chevron-up #{(current_user.voted(post) && current_user.voted(post).up_vote?) ? 'voted' : '' }" ></i> Upvote
Any help would be greatly appreciated...

Try going through the code you've posted line-by-line and look for errors. Here's some to check for:
<!-- Mixing HTML and Ruby on this line -->
<div if vote = current_user.vote(post) %>
The link_to links need some love. Read the docs carefully and note in particular:
Valid HTTP verb values for :method
The path only needs to be specified once
link_to docs here: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
You may want to spend some time getting the indentation right for the if/else/ends as this will make it easier for you to spot syntax errors.

The format of a link_to call is:
link_to "The text in the link", the_path, hash_of_options
That the first argument must be text is what Sergio meant by "link_to must accept label as its first parameter". So, something like:
<%= link_to "Up-vote the post" , post_up_vote_path(post), class: 'btn btn-primary', method: :up_vote do %>
You're giving it a path (or an array that could be converted to a path) as both main arguments.
Check out the docs for the method: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to
Note that your link contains an icon, which should probably take the place of the "label", so your label could just be an empty string.

Related

add erb tag to link_to class in rails

I have a link class like
link_to( class: 'btn_download<%= index %>')
from a .each_with_index model call
Model.each_with_index do |m, index|
but it throws an error
and when i try with #{index} it just adds #{index} to the class name instead of dynamically adding 'index'
As I noticed there are some issues in your code. Please find below the code snippet example I wrote similar to your case which will help you to fix your issue
<% User.all.each_with_index do |m, index| %>
<%= link_to users_path, class: "btn_download#{index}" do %>
<span class="fa fa-sign-out"></span>
Download
<% end %>
<% end %>
So instead of using 'btn_download <%= index %>' try "btn_download#{index}".
Also, Use double quotes
class: "btn btn-primary btn-sm download_btn#{index}"
instead
class: 'btn btn-primary btn-sm download_btn#{index}'
Please let me know if you have any confusion in this.
If you want to wrap your link around an icon, use the following syntax:
<%= link_to ..._path(...) do %>
<i class="fa fa-spin fa spinner"></i>
<% end %>
You have to append a do onto the link to and then close the block with an end. And just put whatever inbetween (icon or image or div).

Rails how to use link_to for an external website and also using a block?

I am trying to use link_to with block and also to link with an external web site, I already know how to use link_to to make my div clickable (learned from here) and also to use link_to to send user to another website (learned from here) but when I try to combine this two approches I got an error:
undefined method 'stringify_keys' for "www.google.com":String
Here is my html.erb code:
<%= link_to #slides[0].link, "#{#slides[0].link}", target: "_blank" do %>
<div class="carousel-item active">
<%= image_tag #slides[0].slide_image.thumb.url, class: "d-block w-100", alt: #slides[0].image_text %>
<div class="carousel-caption d-none d-md-block">
<h5><%= #slides[0].image_text %></h5>
</div>
</div>
<% end %>
I also tried:
<%= link_to #slides[0].link do %> # or
<%= link_to "#{#slides[0].link}", :target => "_blank" do %>
# I got the same error
<%= link_to url_for(#slides[0].link) do %>
# above I got localhost:3000/https://google.com insted of https://google.com
Does anyone know how to do this?
The link_to with block works like this:
link_to(url, html_options = {}) do
# block
end
link_to helper source
So you just have to do :
<%= link_to #slides[0].link, target: "_blank" do %>
#block
<% end %>
(assuming #slides[0].link == "https://google.com" i.e valid external url)

Rendering string with erb content on page

I found many posts with this problem, but it's seems like none of them solves my problem. I got this code which i want to render from string:
<%= button_to "/admin/#{contr_name}/#{obj.id}", method: :delete, class: 'btn btn-danger btn-resource-destroy', data: {toggle: 'tooltip'}, title: 'Delete' do %>
<%= icon('trash-o') %> <span class='sr-only'>Delete</span>
<% end %>
I have tried this:
template += "<div class='col-sm-4'>"
template += "<%= button_to \"/admin/#{contr_name}/#{obj.id}\", method: :delete, class: 'btn btn-danger btn-resource-destroy', data: {toggle: 'tooltip'}, title: 'Delete' do %>
<%= icon('trash-o') %> <span class='sr-only'>Delete</span>
<% end %>"
template += "</div>"
ERB.new(template).result(binding)
but i get syntax errors.
How i can fix this?
I would suggest to use partials instead.
First, define the partial at, for example, views/shared/_delete_button.html.erb:
<%= button_to "/admin/#{contr_name}/#{obj.id}", method: :delete, class: 'btn btn-danger btn-resource-destroy', data: {toggle: 'tooltip'}, title: 'Delete' do %>
<%= icon('trash-o') %> <span class='sr-only'>Delete</span>
<% end %>
Then, you can render the partial with the wanted parameters:
render 'shared/delete_button', contr_name: [contr_name], obj: [obj]
Replacing [contr_name] and [obj] with whatever you want those variables to be assigned to.
Or, even better, allow the partial to extract the controller's name from predefined variables, like this:
<%= button_to "/admin/#{controller.controller_name}/#{obj.id}", method: :delete, class: 'btn btn-danger btn-resource-destroy', data: {toggle: 'tooltip'}, title: 'Delete' do %>
<%= icon('trash-o') %> <span class='sr-only'>Delete</span>
<% end %>
Now you only need to supply the obj when rendering it.
render 'shared/delete_button', obj: [obj]
You could also use named routes, and do [route_name]_path(obj) instead of manually constructing the path.

Adding a Twitter Bootstrap button icon to button_to in Rails

I am working through the Agile Web Development with Rails book but I have been using Twitter Bootstrap instead of the custom styling from the book. I am having trouble adding an icon through GLyphonics to the button_to method. My code looks like this:
<%= button_to <i class="icon-search icon-white">Add To Cart</i>,
line_items_path(product_id: product),
class: "btn btn-success" %>
I have tried quite a few variations but can't seem to get it to work correctly.
I'm not sure how the OP got this to work, but Rails button_to generates an <input type='submit' /> element, which does not allow for HTML in the value field.
See also: input type="submit" Vs button tag are they interchangeable?
The best alternative in this situation is to force link_to to PUT (or POST):
<%= link_to raw("<i class=\"icon-search icon-white\">Add To Cart</i>"),
line_items_path(product_id: product),
class: "btn btn-success",
method: :put %>
You can add the icon as a child element:
<%= button_to button_path, method: :delete do %>
<span class="glyphicon glyphicon-search"></span>
<% end %>
It looks like you have an issue with your quotes:
<%= button_to raw("<i class=\"icon-search icon-white\">Add To Cart</i>"),
line_items_path(product_id: product),
class: "btn btn-success" %>
Enclose the label of the button in double quotes, escape the double quotes in your i tag, and finally, wrap everything into a raw() call to ensure the HTML is properly displayed.
Alternatively you can use html_safe:
<%= button_to "<i class=\"icon-search icon-white\">Add To Cart</i>".html_safe,
line_items_path(product_id: product),
class: "btn btn-success" %>
good point from #jordanpg: you can't have HTML in the value of a button, so his solution is more appropriate and should get the approved status.
the html_safepart remains valid though.
Using raw() or #html_safe still did not work for me.
I am using a helper method to create a button_to flag content. Ended up using the following in my helper method (path is defined beforehand):
form_tag path, :method => :post do
button_tag do
content_tag :i, 'Flag as inappropriate', :class => 'icon-flag flag_content'
end
end
I used this one and it works fine for me :
<%= link_to(line_items_path(product_id: product),
method: :put,
class: 'btn btn-success') do %>
<%= content_tag('i', nil, class: 'icon-search icon-white') %> Add To Cart
<% end %>
Hope this helps
I am using this helper:
module ApplicationHelper
def glyph(*names)
content_tag :i, nil, class: names.map{|name| "icon-#{name.to_s.gsub('_','-')}" }
end
end
Example:
glyph(:share_alt)
=> <i class="icon-share-alt"></i>
and
glyph(:lock, :white)
=> <i class="icon-lock icon-white"></i>
Using Rails 4 and Bootstrap 3, here's how to create a delete button using link_to or button_to.
Note that I'm using Haml instead of Erb.
In your view:
- #users.each do |user|
= link_to content_tag(:i, ' Delete', class: "glyphicon glyphicon-trash"),
users_path(user),
class: "btn btn-danger",
method: :delete,
data: { confirm: "Delete user #{user.username}?" }
You can also replace the content_tag part with
raw('<i class="glyphicon glyphicon-trash"> Delete</i>'),
This work for me, (and with confirm message)
<%= button_to "/home/delete?cardId="+card.id.to_s, data: { confirm:'Are you sure you want to delete?' } do %>
<i class="fa fa-times"></i>
<% end%>
this generate
<form class="button_to" method="post" action="/home/delete?cardId=15">
<button data-confirm="Are you sure you want to delete?" type="submit">
<i class="fa fa-times"></i>
</button>
</form>

Using link_to with embedded HTML

I'm using Twitter's Bootstrap stuff and I have the following HTML:
<a class="btn" href="<%= user_path(#user) %>"><i class="icon-ok icon-white"></i> Do it#</a>
What's the best way to do this in Rails? I'd like to use <%= link_to 'Do it', user_path(#user) %> but the <i class="icon-ok icon-white"></i> is throwing me off?
Two ways. Either:
<%= link_to user_path(#user) do %>
<i class="icon-ok icon-white"></i> Do it#
<% end %>
Or:
<%= link_to '<i class="icon-ok icon-white"></i> Do it#'.html_safe, user_path(#user) %>
I had the same need recently. Try this:
<%= link_to '<i class="icon-ok icon-white"></i> Do it'.html_safe, user_path(#user) %>
You have also the possibility to create an helper method like below:
def link_fa_to(icon_name, text, link)
link_to content_tag(:i, text, :class => "fa fa-#{icon_name}"), link
end
Adapt the classes to your needs.
In normal HTML we do,
<i class="fa fa-user-plus"></i> Register
In Ruby On Rails:
<%= link_to routeName_path do %>
<i class="fa fa-user-plus"></i> Link Name
<% end %>
<%= link_to register_path do %>
<i class="fa fa-user-plus"></i> Register
<% end %>
If you want a link in rails that uses that same icon class from twitter bootstrap all you need to do is something like this.
<%= link_to "Do it#", user_path(#user), :class => "btn icon-ok icon-white" %>
Using HAML:
= link_to model_path do
%img{src: '/assets/someimg.png'}
In the gem twitter-bootstrap-rail : they create a helper glyph
def glyph(*names)
content_tag :i, nil, :class => names.map{|name| "icon-#{name.to_s.gsub('_','-')}" }
end
So you can use it like: glyph(:twitter)
and you link helper could look like: link_to glyph(:twitter), user_path(#user)
I will give this a shot since you haven't accepted an answer yet
and the other answers are not 100% what you were looking for.
This is the way to do it the Rails way.
<%= link_to(user_path(#user), :class => 'btn') do %>
<i class="icon-ok icon-white"> </i> Do it!
<% end %>
Edit: leaving my answer for future reference,
but #justin-herrick has the correct answer when
working with Twitter Bootstrap.
I think you can simplified it through a helper method if you use it frequently in your application.
put it in helper/application_helper.rb
def show_link(link_text, link_source)
link_to("#{content_tag :i, nil, class: 'icon-ok icon-white'} #{link_text}".html_safe,
link_source, class: "btn")
end
Then call it from your view file just like link_to
<%= show_link "Do it", user_path(#user) %>
If you are using the bootstrap 3.2.0, you can use this helper in your app/helpers/application_helper.rb
module ApplicationHelper
def glyph(*names)
content_tag :i, nil, :class => names.map{|name| "glyphicon glyphicon-#{name.to_s.gsub('_','-')}" }
end
end
and then, in your views:
link_to glyph(:pencil) + ' Edit', edit_post_path(#post), class: 'btn btn-warning'
def show_link (source, text)
link_to source, {'data-original-title' => 'Show', 'data-toggle' => 'tooltip', :class => 'btn btn-xs btn-success'} do
"#{text} #{content_tag :i, nil, class:' glyphicon glyphicon-eye-open' }".html_safe
end
end
Helper based on Titas Milan's suggestion, but using a block:
def show_link(link_text, link_source)
link_to link_source, { class: 'btn' } do
"#{content_tag :i, nil, class: 'icon-ok icon-white'} #{link_text}".html_safe
end
end

Resources