How concatenate the link_to in helper? - ruby-on-rails

How to make it work ?
I need puts the two links.
Concatenation << with link_to does not.
module ItemHelper
def edit_links
if user_signed_in? && #item.user_id == current_user.id
html << link_to edit_item_path(#item), class: 'ui button small' do
"<i class='icon edit'></i> Edit"
end
html << link_to item_photos_path(#item), class: 'ui button small' do
"<i class='icon photo'></i> Photo"
end
html
end
end
end

The << operator is actually pushing an object onto an array. It also looks like the html variable is not defined yet. You create the array before your first link, then join it after your last, you should have what you need.
def edit_links
if user_signed_in? && #item.user_id == current_user.id
html = []
# ... existing logic
html.join
end
end

You'll need to start with something before you can append to it with <<, and then you'll need to call #html_safe to prevent Rails from escaping the HTML.
if user_signed_in? && #item.user_id == current_user.id
html = ""
html << link_to "<i class='icon edit'></i> Edit", edit_item_path(#item), class: 'ui button small'
html << link_to "<i class='icon photo'></i> Photo", item_photos_path(#item), class: 'ui button small'
html.html_safe
end

def show_link(link_text, link_source)
link_to link_source, { class: 'ui button small' } do
"#{content_tag :i, nil, class: 'iicon photo'} #{link_text}".html_safe
end
end
Create a helper method in application_helper and using that you can create your link_to tag.

Try this:
def edit_links
if user_signed_in? && #item.user_id == current_user.id
link_1 = link_to edit_item_path(#item), class: 'ui button small' do
"<i class='icon edit'></i> Edit".html_safe
end
link_2 = link_to item_photos_path(#item), class: 'ui button small' do
"<i class='icon photo'></i> Photo".html_safe
end
link = link_1 + link_2
end
end

Related

How to delete a specific Hash key and value that is nested with the same key with a button link

The goal is to remove a specific url from the files.
The Hash -
[{"id":2,"job_id":1358,"files":[{"url":"/uploads/job_photo/files/2/signature.png"},{"url":"/uploads/job_photo/files/2/zombie.jpg"}],"url":"https://www.americanpatiodriveandwalk.com/job_photos/2.json"},{"photos":["signature.png","zombie.jpg"]}]
I separated each url in files so they each have a button.
The View -
<tbody>
<% #job_photos.each do |job_photo| %>
<% job_photo.files.each_with_index do |file, index| %>
<tr>
<td>
<%= file %>
</td>
<td>
<%= link_to file.to_s, title: 'View', class: 'btn btn-xs btn-info', role: 'button' do %>
<i class="material-icons">search</i>
<% end %>
<%= link_to remove_photo_path(job_photo.id, index), title: 'Delete', class: 'btn btn-xs btn-danger', role: 'button', data: { confirm: 'Are you sure?' } do %>
<i class="material-icons">clear</i>
<% end %>
</td>
</tr>
<% end %>
<% end %>
</tbody>
That is the first link results from the code with 0 for the index -
<a title="Delete" class="btn btn-xs btn-danger" role="button" data-confirm="Are you sure?" href="/job_photos/2/photo/0/remove_photo">
I added the index for the route because I figured I would need it eventually.
The Route -
put '/job_photos/:id/photo/:index/remove_photo', to: 'job_photos#remove', as: :remove_photo
If I didn't fail miserably yet...this is where I fall to pieces I think in the controller -
def remove
job_photo = JobPhoto.find(params[:id])
photo_index = JobPhoto.find(params[:index])
job_photo[:files][photo_index].delete(:url)
job_photo.update!(:files)
flash[:success] = "Photo removed!"
redirect_to request.referer || root_path
end
The part where I try to delete the url from the hash doesn't even make sense...but I put it there so show my struggle.
Thanks for any help!
Figured it out -
def remove
#job_photo = JobPhoto.find(params[:id])
total_photos = params[:index].to_i
if total_photos > 0
photo_index = params[:index].to_i
photos = #job_photo.files
delete_image = photos.delete_at(photo_index)
delete_image.try(:remove!)
#job_photo.files = photos
#job_photo.save
else
#job_photo.destroy
end
flash[:success] = "Photo removed!"
redirect_to request.referer || root_path
end
I am sure it can be cleaned up, but works perfectly.

Values of a book saved from amazon have {:value=>""} around it

I'm making an application where the user can search Amazon (with Vacuum) through my application for books, then be able to record the data of the book to their library.
When you search for a book, it goes through every result and puts each in a thumbnail. In every thumbnail there is a button that opens a modal with a form with hidden tags. When the user clicks the submit button, the book's title is saved into a new book. The only problem is that the title is saved like {:value=>"the title of the book that was saved"}
Here is the part of new.html.erb which has the search box:
<%= form_tag({controller: "books", action: "new"}, method: "get", id: "search-form") do %>
<%= text_field_tag :keywords, params[:keywords], placeholder: "Search for a book", class: "form-control" %>
<% end %>
Here is the part of new.html.erb which has the hidden form:
<% #results.each do |result| %>
…
<%= form_for #book do |f|%>
<%= hidden_field_tag :title, class: 'form-control', value: result.name %>
<%= f.submit "Add book", class: "btn btn-default green-hover" %>
<% end %>
…
<% end %>
Here are the new and create actions in my controller:
def new
#book = current_user.books.build if logged_in?
# Search actions
if params[:keywords]
request = Vacuum.new
request.configure(
aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
associate_tag: 'my associate tag is here'
)
keywords = params[:keywords]
params = {
'SearchIndex' => 'Books',
'Keywords'=> keywords,
'ResponseGroup' => "ItemAttributes,Images"
}
raw_results = request.item_search(query: params)
hashed_results = raw_results.to_h
#results = []
hashed_results['ItemSearchResponse']['Items']['Item'].each do |item|
result = OpenStruct.new
result.title = item['ItemAttributes']['Title']
result.url = item['DetailPageURL']
result.image_url = item['MediumImage']['URL']
result.author = item['ItemAttributes']['Author']
result.pages = item['ItemAttributes']['NumberOfPages']
#results << result
end
end
end
def create
#book = #list.books.build(book_params)
if #book.save
flash[:success] = #book.title + "was added to your log."
redirect_to list_path(#book.list_id)
else
render 'books/new'
end
end
I tried to use gsub within book.rb to fix it, but that only changed the text within the flash message and it still saved as {:value=>"the title of the book that was saved"}.
after_create :init
private
def init
puts "Init was called!"
self.title.gsub!('{:value=>"', " ")
self.title.gsub!('"}', " ")
end
How can I change it so that it doesn't save the title with the {:value=>} around it?
I don't think the hidden field tag is right.
<%= hidden_field_tag :title, class: 'form-control', value: result.name %>
Try
<%= hidden_field_tag :title, result.name %>
Your title is being saved as a hash not a string. Use hash accessing methods:
t = title[:value]
puts t #=> "the tile of the book that was saved"

How would I go about adding a button id so I can tell which button has been pressed in Rails

I've got this bunch of code
<%= link_to admin_conference_statuses_path(conference_id: #conference.id), class: "btn btn-primary", method: :post, remote: true do %>
<span id="span">Comm invoiced out Venue</span>
<% end %>
<%= link_to admin_conference_statuses_path(conference_id: #conference.id), class: "btn btn-primary", method: :post, remote: true do %>
<span id="span">Cross charged to Client</span>
<% end %>
And I have this in my controller
def create
conference_id = params[:conference_id] #Keep the same
#conference_status = ConferenceStatus.find_by_conference_id(conference_id)#Keep the same
#conference_status = ConferenceStatus.new unless #conference_status#Keep the same
#conference_status.conference_id = params[:conference_id]
#conference_status.invoiced_out_user_id = current_user.id
#conference_status.invoiced_out_datetime = DateTime.now
if #conference_status.save
# Success
else
# Failure
end
end
Now, when one button is pressed it grabs the id and puts it into a database.
How would I go about adding it so that when button 2 (opposed to button 1) is pressed it puts current user id into a column called "cross_charged_user_id"
If you have the answer could you post it and explain what it does, so I know for next time?
Thanks
Sam
You can pass one extra parameter to second link. Then depending on this extra parameter you can assign the current user as cross_charged_user.
The html code look like:
<%= link_to admin_conference_statuses_path(#conference), class: "btn btn-primary", method: :post, remote: true do %>
<span id="span">Comm invoiced out Venue</span>
<% end %>
<%= link_to admin_conference_statuses_path(#conference, cross_site_to_client: true), class: "btn btn-primary", method: :post, remote: true do %>
<span id="span">Cross charged to Client</span>
<% end %>
And the controller just check the params[:cross_site_to_client] and assign the current user
if params[:cross_site_to_client].present?
#conference_status.cross_site_to_client_id = current_user.id
end
Even You can cleanup your code as well
#conference_status = ConferenceStatus.find_or_create_by_conference_id(params[:conference_id])
if params[:cross_site_to_client].present?
#conference_status.cross_site_to_client = current_user
else
#conference_status.invoiced_out_user = current_user
end
#conference_status.invoiced_out_datetime = DateTime.now
#conference_status.save

Rails: add addtional html into content_tag

In my navigation, I need '.active' to tell user if they are in the current page. So I defined a helper to generate li.active dynamically.
def nav_link(link_text, link_path
class_name = current_page?(link_path) ? 'active' : nil
content_tag(:li, :class => class_name) do
link_to link_text, link_path
end
end
so it can generate
<li class="active">
Resources
</li>
However, for one specific link, I want to add <strong> to the <a> inside <li> to make it stands out from others. How can I do it?
<li class="active">
<strong>Resources</strong>
</li>
UPDATE:
From this
To this
Every nav link(e.g. new,resources, videos) all uses the nav_link helper. What I need, is a way to insert some html(or CSS) into the resouces link. To make it stands out.
Could you not make the change in css?
.active {
font-weight: bold;
}
You can certainly nest content_tag to add strong node:
def nav_link(link_text, link_path, additional_class = nil)
class_name = current_page?(link_path) ? 'active' : nil
content_tag(:li, :class => class_name) do
content_tag(:strong) do
link_to link_text, link_path
end
end
end
Update:
You could check for "Resources" as follows to add the strong tag:
def nav_link(link_text, link_path, additional_class = nil)
class_name = current_page?(link_path) ? 'active' : nil
content_tag(:li, :class => class_name) do
link = link_to(link_text, link_path)
if link_text == 'Resources'
content_tag(:strong) { link }
else
link
end
end
end

content_tag behavior different in view and helper

Someone can explain me why content_tag have a different behavior in view and helpers? A simple code like the one below returns (1) when in the view, but (2) when in the Helper.
arr = ["a", "b", "c"]
concat content_tag(:ul, :class => 'a class') do
arr.each do |item|
concat content_tag(:li, item)
end
end
(1)
<ul class="a class">
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
(2)
<ul>{:class=>"a class"}</ul>
When using content_tag(:ul, '', :class => 'a class') in the Helper, it renders <ul class="a class"></ul>. Why this different behavior too?
The content_tag's behavior is very confusing. I tried some magic with the capture (another confusing method!) method, but without any success.
So... any ideas?
PS.: I'm using rails 4
-------------edit--------------
Since my example is really bad, what I'm really trying to do is somethind like that:
def language_dropdown
content_tag :li, class: "dropdown language" do
concat content_tag(:a, content_tag(:span, I18n.locale, class: "username"),
class: "dropdown-toggle", data: { toggle: "dropdown", hover: "dropdown", "close-others" => "true" } )
concat( content_tag(:ul, class: "dropdown-menu") do
I18n.available_locales.each do |locale|
if locale != I18n.locale
locale_key = "translation.#{locale}"
content_tag :li do
concat(link_to I18n.t(locale_key), url_for(locale: locale.to_s))
end
end
end
end)
end.html_safe
end
This works form me...
module ApplicationHelper
def some_helper arr
content_tag(:ul, :class => 'a class') do
arr.each do |item|
concat(content_tag(:li, item))
end
end
end
end
Remove concat from first content_tag and add brackets into the inner concat method.
Update:
content_tag :li, class: "dropdown language" do
concat(content_tag(:a,content_tag(:span, I18n.locale, class: "username"),
class: "dropdown-toggle", data: { toggle: "dropdown", hover: "dropdown", "close-others" => "true" }))
concat(content_tag(:ul, class: "dropdown-menu"){
I18n.available_locales.each do |locale|
if locale != I18n.locale
locale_key = "translation.#{locale}"
concat(content_tag(:li){link_to(I18n.t(locale_key), url_for(locale: locale.to_s))})
end
end
})
end
The same thing, you need to add brackets and remove the first concat to your code...
Update 2:
items = ""
I18n.available_locales.each do |locale|
if locale != I18n.locale
locale_key = "translation.#{locale}"
items += content_tag(:li) do
link_to(I18n.t(locale_key), url_for(locale: locale.to_s))
end
end
end
label = content_tag(:span, I18n.locale, class: "username")
link = content_tag(:a, label, class: "dropdown-toggle",
data: { toggle: "dropdown", hover: "dropdown", "close-others" => "true" })
content_tag :li, class: "dropdown language" do
concat(link)
concat(content_tag(:ul, class: "dropdown-menu"){ items.html_safe })
end

Resources