mongoid random from controller - ruby-on-rails

is It possible get a shuffle/random of a collection from action in controller.
def action
#pseudocode something like the next:
#objects = Object.random
respond_to do |format|
format.html
end
end
I now can get shuffle from my view, with:
<% #objects.shuffle.each do |microfunc| %>
.
.
.
<% end %>
On view is possible with each or for loop. I don't want use loop to get random Object from one collection.
How can I get random objects inside Mongoid::Criteria from my action controller?

There isn't a great way. Your choices:
Store an integer for each document and get by its value: http://cookbook.mongodb.org/patterns/random-attribute/
use 'skip' which is inefficient: Mongoid random document

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

Linking to the latest post from home page in a Rails application

I'm building a Rails app where I have individual entries called films. I would like to display the latest entry's link on the homepage (separate controller) and I'm struggling to make it work.
My films_controller.rb is as follows (excerpt):
def show
#film = Film.find(params[:id])
end
My home_controller.rb only has the following:
def index
end
And my view file (index.html.erb) has the following:
<%= link_to #film.last.filmTitle, film_path(#film) %>
I'm getting the following error:
Couldn't find Film with 'id'=#<Film::ActiveRecord_Relation:0x007fc93f2d1fd0>
With the #film.find(params[:id]) highlighted.
Thanks!
The last method:
Find the last record (or last N records if a parameter is supplied). If no order is defined it will order by primary key.
source
You can add a #last_film instance variable in your index controller and use it in the view.
def index
#films = Film.all
#last_film = Film.last
end
and in your index.html.erb
<%= link_to #last_film.filmTitle, film_path(#last_film) %>
The index method need something, currently, it didn't connect with ActiveRecord like model or table, that's why
Couldn't find Film with 'id'=#<Film::ActiveRecord_Relation:0x007fc93f2d1fd0>
So if you need to show recent posts in the index then you could something like this
def index
#films = Film.limit(10).order(created_at: :desc) #=> or you can use id
end
it will show last 10 records, for this in the index.html.erb like this
<% #films.each do |film| %>
<%= link_to film.filmTitle, film_path(film) %>
<% end %>
In the other hand if you need to show only one post which is the last then you should modify this query like this like limit(10) to limit(1) or you can use use the last method like this
def index
#film = Film.last
#or
##films = Film.limit(1).order(created_at: :desc) #=> or you can use id
end
if you use this #film = Film.last then your index file will like this
<%= link_to #film.filmTitle, film_path(#film) %>
otherwise, you need to use each method which describes before.

Rails undefined method 'job_app'

So i want to create the view:
1. for normal user, to see it job app status:
def index
#users ||= current_user
#job_apps = #users.job_app
end
It works perfectly on view.
2. Trouble (job_app method undefined) : create view for admins so they can see all candidates:
def empl
#users = User.all.where(:user_type => 'candidate')
#job_apps = #users.job_app.all
end
Note : without #job_apps i can see all the users as well.
I'm going to make a bit of an educated guess here: job_app is indeed a method of the User class, but what you're dealing with in your controller's empl method is not an instance of User, but rather, an instance of ActiveRecord::Relation, which is more or less an array of User objects. User.job_app works because job_app is a member of User, but not of ActiveRecord::Relation.
To achieve what you want, you have to do some iterating through the elements of that array within the view associated with your empl method.
controller code:
def empl
#users = User.all.where(:user_type => 'candidate')
end
view code:
<% #users.each do | user | %>
<%= user.job_app %>
<% end %>

Calling specific instances of a user's objects on their show page

I'm trying to list a user's wanted ads in their show page when they access /users/:id.
In my controller I have:
def show
#user = User.find(params[:id])
#wanted_ads = WantedAd.where(:user_id => params[:id])
And in my show.html.erb I have:
<%= #wanted_ads %>
Binding.pry says #wanted_ads is nil. On the actual page I get #<ActiveRecord::Relation:0x007fa3b5a93408>. This is seemingly a simple thing I'm trying to do -- what am I missing?
The where function returns a ActiveRecord::Relation.
So, you can call first to get the first element, last to get the last one or all to get all elements stored in an array called #wanted_ads.
#wanted_ads = WantedAd.where(:user_id => params[:id]).all
You can then go through this array and choose the attributes you want to pass to the view for each element.
Just a tip:
You should have in your User model an ActiveRecord relation, like this:
has_many :wanted_ads
And in your WantedAd model, like this:
belongs_to :user
And with this, you have a relation of one-to-may.
Then, you can do this:
def show
#user = User.includes(:wanted_ads).find(params[:id])
end
And then, in your view:
<% #user.wanted_ads.each do |wanted_ad| %>
<%# do something %>
<% end %>
where returns a collection of objects, not just a single object. So depending on what's returned you'll want to either call first to get the single instance that ought to return, or call each to iterate over the wanted ads and display them on your page.
You're seeing an instance of ActiveRecord::Relation in pry because of the underlying query mechanism that lazy loads the results. More details can be found here.
Assuming your #wanted_ads is not nil and you want to loop through all the wanted ads...
<% #wanted_ads.each do |wanted_ad| %>
<%= wanted_ad.some_attribute_of_wanted_ad %>
<% end %>
I would also suggest you be aware of SQL injection with the following code in your controller.
#wanted_ads = WantedAd.where(:user_id => params[:id])
As it should be
#wanted_ads = WantedAd.where(":user_id => ?", params[:id])

Rails - Using filter parameters in another controller

On my index page for one of my classes item, I have a form that filters entries in the database. You can filter by all fields that item has and all elements are represented so the code is as follows:
<%= form_tag(url_for({ :controller => :item, :action => :filter }), :id => 'filter_form') do %>
<li>
<% Category.active.each do |category| %>
<% check_box_tag "categories[]", category.id, checked?(:categories, category.id) %>
<%= category.name %>
</li>
...
<% end %>
And the controller in the filter method filters through all entries in Item using the query generated here:
#items = Item.includes(:category, ...)
.joins(:item)
.where(:category => params[:categories]
...
And so on for all fields in the filter.
I also have an export method in the same controller which exports all entries as a CSV file. The view renders what's in a helper method and passes the variable #items which is passed from the export method here as Item.active.
What I'd like is to have another method export_filter that, instead of exporting all entries in the Item table, exports just the filtered entries. In other words I'd like to get these form parameters for my filter form available in my export_filter method and use them to pass to the view and helper. How do I do this?
This is often handled by a single index method using formats (html or csv in your case). The filtering is simply another scope on the list - the rendering is handled by a block within the method, something like:
respond_to do |format|
format.html
format.csv { render text: #products.to_csv }
end
As usual - Railscasts has covered this and is a great resource:
http://railscasts.com/episodes/362-exporting-csv-and-excel?view=asciicast
To set the format - you could either do another button (and look at the value of the button) or another input that helps to select the format.

Resources