Ordering Data by datetime Entry in Rails - ruby-on-rails

I have content_date row in my table that uses the datetime field type. I would like to order my data (content_items) using this field.
models/content_item.rb
class ContentItem < ActiveRecord::Base
belongs_to :calendar
end
models/calendar.rb
class Calendar < ActiveRecord::Base
has_many :content_items
end
controllers/content_items_controller.rb
def index
#calendar = Calendar.find(params[:calendar_id])
end
I tried this, but had no success:
controllers/content_items_controller.rb
def index
#calendar = Calendar.find(params[:calendar_id])
#content_item = #calendar.content_items.order(content_date: :desc)
end
Github Link: https://github.com/JeremyEnglert/baked

This should fix the issue:
#content_item = #calendar.content_items.order('content_date desc')
UPDATE:
I checked your Github repo. You are not using the instance variable in the controller to display the content items. You have to change:
app/views/content_items/index.html.erb
<% #calendar.content_items.each do |content_item| %>
to:
<% #content_item.each do |content_item| %>

#content_items = Calendar.includes(:content_items).order('content_items.content_date desc')
This will solve your problem.

Related

Has_and_belong_to_many association

I have two models with no associations between them. So, I generated a migration and added an association.
class Post < ActiveRecord::Base
has_and_belongs_to_many :workspaces
end
class Workspace < ActiveRecord::Base
has_and_belongs_to_many :posts
end
class CreateJoinTablePostsUsers < ActiveRecord::Migration
def change
create_join_table :posts, :workspaces do |t|
# t.index [:post_id, :workspace_id]
# t.index [:workspace_id, :post_id]
end
end
end
I currently have a page where all the posts are shown. However, I added a multi select in the post creation form in order to select one workspace or more when creating. I would like to be able to show only the posts that were created for that particular workspace instead of all of them, as it is at the moment.
My controller is as follows:
class PostsController < Admin::BaseControlle
def index
respond_to do |format|
format.html
format.json do
#posts = Post.all.order(:order)
render json: present_collection(#posts, PostPresenter).map(&:as_json)
end
end
end
private
def post_params
params.require(:post).permit(:label, :url, :active, workspace_ids: [])
end
end
I am able to get the associated workspace this way:
Post.first.workspaces
But I would like to show all the posts and I get an error when I try this command:
Post.all.workspaces
How could I change my controller and accomplish that? Thank you in advance for your help!
Well you should have a table called PostsWorkspaces by rails convention so you should be able to do something like:
posts_in_workspaces = PostsWorkspaces.all.pluck(:post_id)
Posts.where(id: posts_in_workspaces )
The above will return the posts that have at least one workspace associated, the problem with the approach Post.all.workspaces is that not all posts need to have a workspace (or more than one) associated, also you can think on Post.all like select * from posts which is not what you want to accomplish.
Hope the above helps! 👍
You are thinking about this the wrong way. Post.first.workspaces works because the association is applied on the instance of Post returned. But Post.all returns a collection.
Your best bet is to do something like the following.
# Return all posts that have a workspace associated
posts = Post.joins(:workspaces).all.distinct
posts.each do |post|
post.workspaces
end
If you want to include posts without a workspace
posts = Post.includes(:workspaces).all
posts.each do |post|
post.workspaces
end

I keep getting an undefined method for a class

I've been searching and searching but I cannot find anything to help me with this. I am building an app that allows you to schedule a meeting in a room. The error I'm receiving is
undefined method 'room_id' for #<Room:0x007fa25cc51128>
Here is where the error is occuring in my application.html.erb:
<li><%= link_to "Schedule a Meeting", new_room_meeting_path(#user, #meeting, #room.room_id)%></li>
Here is my meetings controller:
class MeetingsController < ApplicationController
before_action :authenticate_user!
def new
#meeting = Meeting.new
#rooms = Room.all
#room = Room.find(params[:room_id])
end
def index
#meetings = Meeting.all
end
def show
#meeting = Meeting.find(params[:id])
#comments = #meeting.comments
#room = Room.find(params[:id])
end
def create
#user = User.find(params[:user_id])
#meeting = #user.meetings.create(meeting_params)
NotificationMailer.meeting_scheduled(#meeting).deliver_now
if #meeting.save
redirect_to root_path, flash: { notice: "Congratulations!!! Your meeting has been scheduled successfully!!!"}
else
render :new
end
end
private
def meeting_params
params.require(:meeting).permit(:name, :start_time, :end_time, :user_id, :room_id)
end
end
Here is my Meeting model:
require 'twilio-ruby'
class Meeting < ActiveRecord::Base
belongs_to :user
belongs_to :room
has_many :comments
validates_presence_of :user_id, :room_id, :name
def meeting_author_email
user.try(:email)
end
def self.send_reminder_text_message(body, phone)
#account_sid = ENV['twilio_account_sid']
#auth_token = ENV['twilio_auth_token']
#from_phone_number = ENV['twilio_phone_number']
#twilio_client = Twilio::REST::Client.new(#account_sid, #auth_token)
#twilio_client.account.messages.create( to: phone,
from: #from_phone_number,
body: body
)
end
def start_timestamp
(start_time - 6.hours).strftime('%b %e, %l:%M %p')
end
def end_timestamp
(end_time - 6.hours).strftime('%b %e, %l:%M %p')
end
end
The correct URI is: /rooms/:room_id/meetings/new(.:format)
I don't know what the problem is and it is really frustrating me. Any help would be greatly appreciated. I've searched over and over and have been unable to resolve this.
Thanks.
Your Room model doesn't have a column called room_id, but it does have a column called id. Every object in your application has an automatically generated id column as part of the "magic" of Rails. The room_id column that you seem to want belongs to the meetings table, but you indicated that it should come from your room object.
Replace the line:
Schedule a Meeting", new_room_meeting_path(#user, #meeting, #room.room_id)%></li>
with:
Schedule a Meeting", new_room_meeting_path(#user, #meeting, #meeting.room_id)%></li>
Since you stated the URI is "/rooms/:room_id/meetings/new(.:format)", the first part of the fix is to use the :id attribute instead of the: room_id attribute on your #room object, and second to remove the unnecessary objects from your route. You only need the id attribute for a valid URI:
<li><%= "Schedule a Meeting", new_room_meeting_path(#room.id)%></li>
Turns out I was calling the wrong URI.. The correct one was:
<li><%= link_to "Schedule a Meeting", new_user_meeting_path(current_user) %></li>
Is what did the trick. I also made the mistake of not dealing with seed data properly which really threw me for a loop. So once again, THANKS again to all who helped me out. I was working on an old project so I had a lot to go over.

Only show registers from a current_user Rails 4

I'm trying to show only the registers (patients) from a user (medic) that creates the register
In my controller I have:
def index
# #patients = Patient.all
#medic = Medic.find(params[:id])
#patients = #medic.patients
end
I get error: Couldn't find Medic with 'id'=
In my view I have:
<% #patients.each do |patient| %>
<%= patient.name %>
<% end %>
In my models I have:
class Medic < ActiveRecord::Base
has_many :patients
end
class Patient < ActiveRecord::Base
belongs_to :medic
end
¿How can I do this?
Thanks for help!
You can not have params[:id] by default in your index method; it is a collection route not a member route. So always the value of params[:id] is nil
If you would like to index patients of a certain medic you can go to localhost:3000/patients?medic_id=x and in your controller use
if params[:medic_id]
#patients = Patient.where(medic_id: params[:medic_id]).all
else
#patients = Patient.all
end
If you use devise and you have a current_medic defined then just get patients for the current medic using
#patients = current_medic.patients
localhost:3000/patients will now display patients or logged in user.
You have to add a before_action :authenticate_medic! to your controller.

Save external Tweets in database in Rails

I am new to rails developement and to the MVC architecture. I have a little application where I can add Videos' URLs from Dailymotion or Youtube and get the tweets related to that URL using the twitter gem in Ruby on Rails.
Now i'm able to store the tweets like this : (This is the video controller)
def show
#video = Video.find(params[:id])
# Creating a URL variable
url = #video.url
# Search tweets for the given video/url
#search = get_client.search("#{#video.url} -rt")
# Save tweets in database
#search.collect do |t|
tweet = Tweet.create do |u|
u.from_user = t.user.screen_name.to_s
u.from_user_id_str = t.id.to_s
u.profile_image_url = t.user.profile_image_url.to_s
u.text = t.text.to_s
u.twitter_created_at = t.created_at.to_s
end
end
I'm not sure if this is the right way to do it (doing it in the controller ?), and what I want to do now is to specify that those tweets that have just been stored belong to the current video. Also I would like to have some sort of validation that makes the controller look in the database before doing this to only save the new tweets. Can someone help me with that ?
My models :
class Video < ActiveRecord::Base
attr_accessible :url
has_many :tweets
end
class Tweet < ActiveRecord::Base
belongs_to :video
end
My routes.rb
resources :videos do
resources :tweets
end
This is an example of a "fat controller", an antipattern in any MVC architecture (here's a good read on the topic).
Have you considered introducing a few new objects to encapsulate this behavior? For example, I might do something like this:
# app/models/twitter_search.rb
class TwitterSearch
def initialize(url)
#url = url
end
def results
get_client.search("#{#url} -rt")
end
end
# app/models/twitter_persistence.rb
class TwitterPersistence
def self.persist(results)
results.map do |result|
self.new(result).persist
end
end
def initialize(result)
#result = result
end
def persist
Tweet.find_or_create_by(remote_id: id) do |tweet|
tweet.from_user = screen_name
tweet.from_user_id_str = from_user_id
tweet.profile_image_url = profile_image_url
tweet.text = text
tweet.twitter_created_at = created_at
end
end
private
attr_reader :result
delegate :screen_name, :profile_image_url, to: :user
delegate :id, :user, :from_user_id, :text, :created_at, to: :result
end
Notice the use of find_or_create_by ... Twitter results should have a unique identifier that you can use to guarantee that you don't create duplicates. This means you'll need a remote_id or something on your tweets table, and of course I just guessed at the attribute name (id) that the service you're using will return.
Then, in your controller:
# app/controllers/videos_controller.rb
class VideosController < ApplicationController
def show
#tweets = TwitterPersistence.persist(search.results)
end
private
def search
#search ||= TwitterSearch.new(video.url)
end
def video
#video ||= Video.find(params[:id])
end
end
Also note that I've removed calls to to_s ... ActiveRecord should automatically convert attributes to the correct types before saving them to the database.
Hope this helps!

Passing instance variables into API in rails

I'm trying to pass in some instance variables to call an API with that specific object's attributes. A user fills in their car details (make, model, and year) which creates an offer object. That is supposed to be passed into Edmund's API to retrieve the info for that car. The code works fine if I set it with a specific make/model/year but I can't make it return info for a created offer object.
Here's my controller:
def show
#offer = Offer.find(params[:id])
#wanted_ad = WantedAd.find(params[:wanted_ad_id])
#make = #offer.ownermake
#model = #offer.ownermodel
#year = #offer.owneryear
respond_to do |format|
format.html # show.html.erb
format.json { render json: #offer }
end
end
And here's my model:
class Offer < ActiveRecord::Base
attr_accessible :user_id, :wanted_ad_id, :estvalue, :image1, :offerprice, :ownercartype, :ownerdesc, :ownermake, :ownermileage, :ownermodel, :owneryear
belongs_to :user
belongs_to :wanted_ad
has_one :car
def self.carsearch
#car = []
carinfo = HTTParty.get("http://api.edmunds.com/v1/api/vehicle/#{make}/#{model}/#{year}?api_key=qd4n48eua7r2e59hbdte5xd6&fmt=json")
carinfo["modelYearHolder"].each do |p|
c = Car.new
c.make = p["makeName"]
return carinfo
end
end
end
My car model is simply:
class Car < ActiveRecord::Base
attr_accessible :make, :model, :year
belongs_to :offer
end
And I'm trying to call it from a view file with <%= Offer.carsearch %>. I'm probably all sorts of messed up but this is my first time working with an API and I'm very lost.
I think you got several logical errors in your carsearch method:
You're fetching a carinfo, iterate through an array, instantiate a new car but nothing happens with the c object and at the end of the first iteration you exit the whole function returning the retrieved carinfo...
Is this probably what you've meant?
def carsearch
#cars = []
# where do `make`, `model` and `year` come from here?
# probably method parameters!?
carinfo = HTTParty.get("http://api.edmunds.com/v1/api/vehicle/#{make}/#{model}/#{year}?api_key=qd4n48eua7r2e59hbdte5xd6&fmt=json")
carinfo["modelYearHolder"].each do |p|
c = Car.new
c.make = p["makeName"]
# initialize other attributes (year, model)?
#cars << c
end
return #cars
end

Resources