Using exists? in Rails 4 - ruby-on-rails

I am trying to query the DB to see if an Open House exists for a specific listing. If it does, I would like it to display a span. I created a helper based on what I read, but the span is displaying on all of the listings, not just the ones that have an upcoming open house. Any help is appreciated.
ApplicationController:
class ApplicationController < ActionController::Base
def upcoming_oh
if #open_houses = OpenHouse.exists?
end
end
helper_method :upcoming_oh
end
Listings Index:
<% upcoming_oh %><span class="label label-nklyn-yellow">Upcoming Open House</span>

You can check if your model contains a specific record using exists function
if OpenHouse.exists?(your_record)
# do stuff
end
I'm not sure what is OpenHouse, but I think it's a model of your's, anyway this logic should solve your issue
you can use if/else to display/hide a span or div or whatever you want after that like this
<% if #condition %>
<span>
<% end %>

Related

Render results on #show without storing data in ActiveStorage

I'm learning RoR by building my first app (yay!). I gotta a question thought as rails guides do not cover this topic:
How to render unique results on #show to a user without storing any data in a model?
Steps I want to take:
Create a basic index view with a form_tag that will allow user to submit a link (string) and click submit button
Write Service Objects that will allow me to parse that link and create a response I want user to see
I want to write a #show method in a separate controller that will allow me to display all the data. (I also want to parse my params[:link] in that method using Service Objects.
I want to finally display this data in a table in #show view (probably I need to create a unique #show/[:id] for each user?
Here's what my app looks like at the moment (more or less):
Static Controller (just to render index.html.erb with a form)
class StaticController < ApplicationController
def index
end
end
Static Index view (yup, parsing imgur link here)
<h1>Hello Rails!</h1>
<%= form_tag("/images", method: "post") do %>
<p>
<%= label_tag(:imgur_link) %><br>
<%= text_field_tag(:imgur) %>
</p>
<p>
<%= submit_tag("Get my cards") %>
</p>
<% end %>
Images Controller (where all the magic SHOULD happen)
class ImagesController < ApplicationController
def show
#collection = params[:imgur_link]
#service1 = service1.new(*args).call
#service2 = service2.new(*args).call
...
end
end
Images Show view
Empty as I'm stuck with the Images controller at the moment.
Any help would be more than appreciated.
Thanks!
There is no reason you should put something into storage just in order to display it. If you get to a point when you have the results in your controller, you could just pass them to view in some #variable
As I see, you have set up the form for step 1. If you also have routes.rb call 'images#show' for POST /images, then you will have params[:imgur_link] available in your show action. This should do:
# config/routes.rb
YourApplication.routes.draw do
# ...
post '/images' => 'images#show'
end
Now you have to somehow process that link. Since I don't know what your results should be, I'm going to assume that you have two classes, Service1 and Service2, both of which accept an URL and return collection of results, and both collections hold the elements of the same class. Then you can leave only unique results for your show view, like this:
# app/controllers/images_controller.rb
class ImagesController < ApplicationController
def show
link = params[:imgur_link]
results1 = Service1.new(link).results
results2 = Service2.new(link).results
#results = (results1 + results2).uniq
end
end
Then you can do something with #results in your show view. E.g.
# app/views/images/show.html.erb
<% #results.each do |result| %>
<%= result.inspect %>
<% end %>

How to filter collections in rails

I'm new in Rails, and I'm trying to filter the animals I have on my DB, by one of their properties. I have read that I can make it by a scope in the controller, and have access to it by a parameter on the URL, but I think that doesn't work for me because I'm using a loop to create my HTML.
Is there a way to add a filter to the collection I'm using (#animals)?
<% #animals.each do |animal| %>
<li>
<a href="#">
<%=link_to animal.ncommon, animal %>
</a>
</li>
<% end %>
I hope I was clear with my question. Thank you for your help!
So the best practice is to move the scope to the models , not in the controller. Here is and example. (please note that this may change depending on your file structure and names).
here I'm going to filter animals by type. Lets say type 1 and type 2.
#model app/models/animal.rb
class Animal < ActiveRecord::Base
scope :by_type, -> (ty) { where(type: ty) }
end
#controller app/controllers/animals_controller.rb
class AnimalsController < ApplicationController
... other code
def index
# calls the by_type method/scope in the Animal model
# filter the records and assignes them to #animals varaible
#animals = Animal.by_type(params[:type])
end
... other code
end
then you can use your loop in the view. When you want to filter, you call the index action with a parameter
E.g http://localhost:3000/animals?type=1
So the idea is, not to filter inside the loop, but to get the filtered results to the #animals variable.
I just found a solution that i can use in the loop.
I changed:
<% #animals.each do |animal| %>
to:
<% #animals.where("promo > ?", 0).each do |animal| %>
Here i´m getting all the animals that has a promo greater than zero.
Thanks!

How should I remove this logic from my view in Rails?

I have a Rails app with events, and when an event's end date has passed I want to include an element on event#show pages indicating that the event is expired.
Right now I have this logic in my view like this:
<% if #event.end_time <= Time.now %>
<h4 class="label--warning">This event has already happened</h4>
<% end %>
I understand it's good to strip logic out of views and I don't want to hit the database from the view, so I'm wondering what the best way to do that would be for a case like this?
If you are loading the page for an #event you have already hit the database. So that code in your view will not generate an extra database query.
The logic in your view (whether or not an event is expired) can be moved to the model. But you're still going to have some code in the view. The nice thing about moving it to the model, however, is that you can easily write tests for the model class.
Model:
def is_expired?
end_time <= Time.now
end
View:
<% if #event.is_expired? %>
<h4 class="label--warning">This event has already happened</h4>
<% end %>
Instead of having conditional logic in the view you could always use view helpers.
=> app/helpers/expired_event.rb
Module ExpiredEvent
def event_expired?(event)
if event.end_time <= Time.now
return "<h4 class="label--warning">This event has already happened</h4>".html_safe
end
end
end
then in your view
<%= event_expired?(#event) %>
Something like that?

Ruby On Rails Display Image

I am a newbie at it.I have just educated myself for 2 days. And a have a problem.
Example: I have a table , called as tblData, includes 2 columns: id, img_link. img_link contains link to an image.
I want to show all of them in this table(id and image, not image link) into a html file.
So, exactly what I need do?
If you have an image link that you can pull from your database, you can do something like this:
Assuming you have an object assigned and everything's set up:
In your controller for tbl_data (e.g. app/controllers/tbl_data_controller.rb):
class TblDataController < ApplicationController
def your_action
#tbl_data_item = TblData.first
end
end
(The code above is just an example, you should substitute for whatever code/query you wish to run)
In your view template, you can render an image from a link using the following Rails view helper:
<%= image_tag(#tbl_data_item.img_link) %>
This would output the following HTML:
<img src="/path/to/image/from/img_link" />
There's a lot more info on this helper on the Rails api docs. The Rails Guides has some awesome info on getting things set up and running as well. Hope this helped!
UPDATE:
To give you a better example with clearer steps, you would do something like the following:
Set up your routes (app/config/routes.rb):
Rails.application.routes.draw do
resources :tbl_data
end
Create your model, used to communicate with its respective database table (app/models/tbl_data.rb):
class TblData < ActiveRecord::Base
# your model-specific code goes here - validations, scopes, etc.
end
Create the controller, which responds to when a user hits a certain route in your app (app/controllers/tbl_data_controller.rb):
class TblDataController < ApplicationController
def your_action
#tbl_data_items = TblData.all
end
end
Create the view template, that will be rendered for your user(app/views/tbl_data/your_action.rb):
<table>
<% #tbl_data_items.each do |item| %>
<tr>
<td><%= item.id %></td>
<td><%= image_tag(item.img_link) %></td>
</tr>
<% end %>
</table>
The above would show a table with each record in the #tbl_data_items as a row, with 2 columns, one with the id, and one with the actual image for that item.
Create a folder in public called images, put the desired image in that folder.
Put <%=image_tag 'whatevertheimagefilenameis.png', class: 'example-class', id: 'example-id'%> in the html.

Admin-editable views

There doesn't appear to be a gem for this, and I think a CMS is overkill as the client only wants to edit the welcome message on the home page!
Here's what I think I should do:
1) Create Page model:
rails g model Page name:string
2) Create Field model:
rails g model Field name:string content:string page_id:integer
3) Create relationship, Page h1:b2 Field
4) Create rake task to set up the message field that belongs to the welcome page:
namespace :seeder do
namespace :initial_seed do
task pages: :environment do
p = Page.create(name: "Welcome")
p.fields.create(name: "welcomemessage", content: "everything goes here. The long rambling welcome!")
end
end
end
5) Create a 'static' controller for the 'static'-ish pages. The home, the about us etc...
class Static < ApplicationController
def home
#fields = Page.where().fields
end
end
6) In the view, populate the welcome message from the database (I'll create a helper for this):
<% field = #fields.find {|x| x[:name] == 'welcomemessage' } %>
<%= field.content %>
So that's the reading done. Now onto the creation, updation and deletion:
6) Create a control panel controller:
class Panel < ApplicationController
def pages
#pages = Page.all
end
end
7) Display fields in the view at panel/pages.html.erb: (I'll use partials here)
<% #pages.each do |page| %>
Title: <%= page.name %>
<% page.fields.each do |field|%>
Field: <%= field.name %>
<% form_for(field) do |f| %>
<% f.text_area :content%>
<% f.submit %>
<%= end %>
<% end %>
<% end %>
Now this is just a rough run down of what I want to do. There are a few problems I want to query, though.
Is this sort of how you would do this?
How should I configure my routes? What is a clever way of populating the #fields variable (see step 5) with the fields for the page we're viewing?
If I do have a panel/pages.html.erb view, should it simply display all of the editable fields in text areas? How should it update these areas? Multiple submit buttons inside multiple forms? What if someone wants to edit many fields at once and submit them all at once?
Where should these forms go? Should I create multiple RESTful actions all inside the Panel controller like this?:
class Panel < ApplicationController
# new and create not present as the pages have to be created manually
# Enabling the user to create their own pages with their own layouts is a bit insane
def pages
#pages = Page.all
end
def pages_update
end
def pages_destroy
end
end
Multiple restful routes in one controller doesn't strike me as organised, but it would make it easier to lock down the panel controller with a before_action hook to redirect if not admin...
Also, I'm nearing the end of a big job, and all I need to do is add the ability to edit one field on one page and them I'm done and I really don't want to have to figure out alchemy_cms or whatever. In future, yes, but, please, please, please someone give me some small pointers here.
I would strongly advise against building your own CMS. It's fraught with difficulties, and it seems like you're running up against some of those now. You should go and check out something like AlchemyCMS.

Resources