How do I place a link at the top of my page when the URL that it is pointing to is not determined until later down the page. In this example, I want to move Create and Edit Scenario links to the top of the page, but as you can see Edit Scenario depends on knowing the #scenario_id first.
<%= will_paginate #scens, :next_label => 'Older', :prev_label => 'Newer' %>
<div class="box">
<% for scenario in #scens %>
<% #created = scenario.created_at %>
<% #updated = scenario.updated_at %>
<% #scenario_id = scenario.id %>
<% if scenario.scenario_image.exists? %>
<%= scenario_image_tag(scenario) %>
<% end %>
<%= simple_format(scenario.description) %>
<% end %>
</div>
<% if session[:role_kind] == "controller" %>
<p>
<%= button_to "Create new scenario", :action => "create" %>
<% if #scens.size > 0 %>
<%= button_to "Edit scenario", :action => "edit", :id => #scenario_id %>
<% end %>
</p>
You can add the link at the top but you will need to programmatically access it later and then assign the URL to it. That needs some kind of reference or look-up capability, I'm thinking client-side javascript but that's as I don't know Ruby.
Alternatively you could create the link later when you have the URL and place the link at the top using CSS positioning. The actual position of all the DOM elements on the page need not match the order in which they are rendered.
One way to do this is to use a helper:
In your helper.rb file:
def stack_example(scens, &block)
html = 'Scenario Details'
edit_link = 'Edit Link'
yield html, edit_link
end
Then in your partial you could have something like:
<% stack_example(#scens) do |html, edit_link| %>
<%= edit_link %><br>
<%= html %>
<% end %>
Should output the following:
Edit Link
Scenario Details
I don't get it. Why do you create model in the view layer? Why wouldn't you create the model variables in the controller? Sth like:
class your_controller
def your_method
#scenario_id = ...
end
end
I think that your problem lays in the invalid MVC usage. Don't you think that all the #member #variables should be initialized before the view starts to render?
Related
Well my problem is when i call my model Question and show in a .each do, my view show the ActiveRecord but i don't now how to hide this or the right way to show my questions without the ActiveRecord.
In my view the content show like this:
<%= #questions = Question.all.order(:id).reverse_order %>
<% #questions.each do |question| %>
<% if #course.id == 1 %>
<h5><%= link_to question.title, question , class: 'reply text-light text-decoration-none' %></h5>
<% end %>
<% end %>
What is the difference between <%, <%=, <%# and -%> in ERB in Rails?
You could use <% %> instead of <%= %>:
<% #questions = Question.all.order(id: :desc) %>
And it's better to put that to controller:
class QuestionsController
def index
#questions = Question.all.order(id: :desc)
end
end
I found a solution if i want to call a Model in view, just create a input type="hidden" like this:
<input type="hidden" value="<%= #questions = Question.all.order(:id).reverse_order %>">
You should use url_helpers provided by Rails. See Examples provided under link_to docs.
Also I would suggest to follow the recommendation at https://stackoverflow.com/a/66470651/936494 and in your view change following
<h5><%= link_to question.title, question , class: 'reply text-light text-decoration-none' %></h5>
to
<h5><%= link_to question.title, question_path(question), class: 'reply text-light text-decoration-none' %></h5>
And if you don't have url_helpers available, then the 2nd argument should be a URL to a resource in your application.
Hope that helps. Thanks.
I’m completely new to ruby on rails, I’m creating a simple article search application that would use the Guardian API and just display the news titles. It just needs to work like this: a user enters the page, fills in the search form and views the news titles.
I want to simply select the request result’s ‘webTitle’ keys and display their values as list items, but I get a big chunk of data and I’m not sure how can I do that.
Here is the request result:
{"response"=>{"status"=>"ok", "userTier"=>"developer", "total"=>2153270, "startIndex"=>1, "pageSize"=>10, "currentPage"=>1, "pages"=>215327, "orderBy"=>"relevance", "results"=>[{"id"=>"books/2017/jul/16/fall-down-7-times-get-up-8-naoki-higashida-review-autism", "type"=>"article", "sectionId"=>"books", "sectionName"=>"Books", "webPublicationDate"=>"2017-07-16T06:00:13Z", "webTitle"=>"Fall Down 7 Times Get Up 8 review – a window on the world of autism", "webUrl"=>"https://www.theguardian.com/books/2017/jul/16/fall-down-7-times-get-up-8-naoki-higashida-review-autism", "apiUrl"=>"https://content.guardianapis.com/books/2017/jul/16/fall-down-7-times-get-up-8-naoki-higashida-review-autism", "isHosted"=>false, "pillarId"=>"pillar/arts", "pillarName"=>"Arts"}, {"id"=>"football/2017/jul/07/gold-cup-2017-predictions-usa-mexico-costa-rica-football", "type"=>"article", "sectionId"=>"football", "sectionName"=>"Football", "webPublicationDate"=>"2017-07-07T09:00:08Z", "webTitle"=>"Gold Cup picks: USA to tip under-strength Mexico and in-form Costa Rica", "webUrl"=>"https://www.theguardian.com/football/2017/jul/07/gold-cup-2017-predictions-usa-mexico-costa-rica-football", "apiUrl"=>"https://content.guardianapis.com/football/2017/jul/07/gold-cup-2017-predictions-usa-mexico-costa-rica-football", "isHosted"=>false, "pillarId"=>"pillar/sport", "pillarName"=>"Sport"}, {"id"=>"world/2017/jul/15/stream-of-floating-bodies-near-mosul-raises-fears-of-reprisals-by-iraqi-militias", "type"=>"article", "sectionId"=>"world", "sectionName"=>"World news", "webPublicationDate"=>"2017-07-15T08:00:01Z", "webTitle"=>"Stream of floating bodies near Mosul raises fears of reprisals by Iraqi militias", "webUrl"=>"https://www.theguardian.com/world/2017/jul/15/stream-of-floating-bodies-near-mosul-raises-fears-of-reprisals-by-iraqi-militias", "apiUrl"=>"https://content.guardianapis.com/world/2017/jul/15/stream-of-floating-bodies-near-mosul-raises-fears-of-reprisals-by-iraqi-militias", "isHosted"=>false, "pillarId"=>"pillar/news", "pillarName"=>"News"}]}}
API consumer class:
#app/clients/guardian_api_client.rb
class GuardianApiClient
include HTTParty
API_KEY = ENV['GUARDIAN_CONTENT_API_KEY']
BASE_URL ="https://content.guardianapis.com/search?"
API_PARTIAL_URL = "api-key=#{API_KEY}"
def query(q)
request = HTTParty.get(BASE_URL+"q=#{q}&""api-key=#{API_KEY}")
puts request
request
end
end
Controller:
class SearchController < ApplicationController
def search
#app = GuardianApiClient.new
#results = #app.query(params[:q])
end
end
View:
<%= form_with(url: '/search') do |f| %>
<%= f.text_field :q %>
<%= f.submit 'search' %>
<% end %>
<% if #results != nil %>
<ul>
<%= #results.each do |r| %>
<li><%= r["webTitle"] %></li>
<% end %>
</ul>
<% else %>
<p>No results yet</p>
<% end %>
Routes:
Rails.application.routes.draw do
get '/search' => 'search#search'
post '/search' => 'search#search'
end
The response is some JSON, so you need to learn how to map through it and get the results that you want.
To see the data more clearly try printing it with:
puts JSON.pretty_generate(#results)
in your controller, then see the output in your rails console.
Anyway, you have a few options:
Option 1: Likely you just need to drill down further into #results in your view. In the JSON that is returned, the webTitles are nested, so changing the third line below should work. Also note on that line that I removed the = sign to prevent the return value from being displayed.
<% if #results != nil %>
<ul>
<% #results["response"]["results"].each do |r| %>
<li><%= r["webTitle"] %></li>
<% end %>
</ul>
<% else %>
<p>No results yet</p>
<% end %>
Option 2: You may consider getting the list of articles in your controller, which I think was your original intent and also is probably more "rails" like:
class SearchController < ApplicationController
def search
#app = GuardianApiClient.new
#results = #app.query(params[:q])
#articles = #results["response"]["results"].map do |article|
article
end
end
end
In your view, then call render to a partial:
<%= render 'articles' %>
Then create a partial view called _articles.html.erb in whatever directory your other view is in, and then add some code to display each article:
<ul>
<% #articles.each do |article| %>
<li><%= article["webTitle"] %> <% link_to 'Link', article["webUrl"] %></li>
<% end %>
<ul>
By separating out each article that was returned in the #articles array, it will probably be easier for you to get other attributes as well in a more readable way. As you can see, above I included a link to the actual article.
In my controller i find a uniq notebook and user name.
but i want to be able to check in my html code that it shows only one type of user.
in controller
def index
#allnotebooks = Note.uniq.pluck(:string, :notebook)
#notes = Note.all
end
in my html
<% #allnotebooks.each do |notebook| %>
<% if notebook.string == c_user.name %>
<option><%= notebook %></option>
<% end %>
<% end %>
notebook.string does not work. what am i missing
Also you can do in different way other than using pluck, using select you can do it
like-
In controller code-
def index
#allnotebooks = Note.uniq.select([:string, :notebook])
#notes = Note.all
end
in your html
<% #allnotebooks.each do |notebook| %>
<% if notebook.string == c_user.name %>
<option><%= notebook %></option>
<% end %>
<% end %>
Thanks!!!
Pluck returns an array.
Try notebook.first or notebook[0]
Docs here: http://apidock.com/rails/ActiveRecord/Calculations/pluck
Second example at the bottom applies here.
In your example it should be:
<% #allnotebooks.each do |notebook| %>
<% if notebook[0] == c_user.name %>
<option><%= notebook[1] %></option>
<% end %>
<% end %>
btw you might want to improve this by only loading notebooks where the string equals your user's name.
I am not a good ruby guy, You can write it like
<% #allnotebooks.each_with_index do |notebook, index| %>
<%= notebook[index].string %> => <%= notebook[index].notebook %>
<% end %>
for "a" unique notebook, you do you need to loop it?
just to say:
#allnotebooks.each{|notebook| <%= notebook[0] %> <%= notebook[1] %> }
But there can be better ways.
When writing an HTML file, why use <%= INSERT RAILS HERE %> vs. <% INSERT RAILS HERE %>
<%= %> emits a string, <% %> runs code.
On the pedantic side, you're writing an ERb template, not an HTML file--the syntax is the same whether it's a template for HTML, JS, or whatever.
The ERB docs provide additional (but not complete) information.
<%= %> will return value and display in your page. Assume that you have person.name = 'Dark'
<%= person.name %>
will display Dark in your web page.
<% %> will not return any value to your page. It just embed simple ruby code. Usually used with `control statement'.
<% if person.present? %>
<span><%= person.name %></span>
<% end %>
When we use <%= %> it simply displays the value returned, on the html page.
<% %> executed the code but doesn't dispaly it on the html page.
In my example I want RoR to display an image when I'm listening to Pearl Jam.
Winamp writes 'currently playing' info to np.txt.
<%= data = File.read("np.txt")
if data.include? "Pearl Jam"
<img src="space.jpg" alt="sagan"/>
end
%>
However I'm not sure how to get HTML tags to work inside RoR code.
I think what you want is:
<% data = File.read "np.txt" %>
<% if data.include? "Pearl Jam" %>
<img src="space.jpg" alt="sagan"/>
<% end %>
In ERB anything rendered outside of the <% %> tags is HTML.
ian.
You should use an image tag.
<%- data = File.read "np.txt" -%>
<%= image_tag("space.jpg", :alt => "sagan") if data.include? "Pearl Jam" %>