Selecting content to feature - ruby-on-rails

in my Rails app users are able to write and publish posts.
On the homepage, I want to feature a couple of posts.
This is what I'm using to select posts at the moment:
posts_controller.rb
favorite_post_ids = [8,2,5]
#favorite_posts = Post.find(favorite_post_ids)
new_post_ids = [1,2,5]
#new_posts = Post.find(new_post_ids)
and then in the view I loop over them to display the posts.
However, once a post is deleted and the controller can no longer find it, I get an error that says
Couldn't find all Posts with 'id': (1, 2, 5) (found 2 results, but was looking for 3)
What's a better way to do this? I was thinking of individual tables, one for new_posts and one for favorite_posts and then do a relationship to posts. In the table I will have post_id referenced.
UPDATE :
I added a bunch of extra columns to posts with different types of featured content all with boolean values defaulted to false. I assign true if I want them featured.

How would you solve this problem?
Make your posts have flag favorite of type boolean. Then you'd select them like this:
#favorite_posts = Post.where(favorite: true).limit(3)
And for new posts, you can use the timestamp
#new_posts = Post.order(created_at: :desc).limit(3)
Look, no hardcoding!

I dont encourage hardcoding. But still if that is your requirement, try
favorite_post_ids = [8,2,5]
#favorite_posts = Post.where(:id => favorite_post_ids)
new_post_ids = [1,2,5]
#new_posts = Post.where(:id => new_post_ids)

Related

Ruby on Rails blog application posts display

I was wondering if there's a way to display both my last post created and also the latest three post created in the same page.
So this is how it looks now.what I want is to keep the left column like it is,but on the right column I want my last 3 posts to be displayed:
In my welcome_controller.rb I have this index method defined #post =Post.limit(1).order("created_at desc")that limits the posts to one but if I change it to 3 it applies to both left and right column and I get this really ugly thing]:
You can retrieve last 3 posts by this query
#posts = Post.last(3)
You could define your data in the action, like
#created_post = Post.limit(1).order("created_at desc")
#last_three_posts = Post.limit(3).order("created_at desc")
and change your view accordingly but the created post will always be in the last three so you could use just #last_three_posts
#last_three_posts = Post.limit(3).order("created_at desc")
#created_post = #last_three_posts.first

Rails checking if an object is also assigned to another

in my Rails application I've got a n:m relation between movies and tags. (has_and_belongs_to_many)
So each tag can be assign to several movies.
Now when I add new tags to a movie I want to check If this Tag is already assigned to this movie.
What is the esiest way in rails to check if there is a relation ship between the tag and the movie?
I fetch the tag with:
#tagfound = Tag.where("tagname = ?", data[:tagname])
The List with all Tags from the movie can be fetched with this:
#vid.tags
Thanks for your help
You may not need to check. You can simply do this
movie.tags = [array, of, tags]
movie.save # note, you don't need to save. The line above saves.
or
movie.tag_ids = [1,2,3,4]
movie.save # note, you don't need to save. The line above saves.
and that will take care of it setting new tags and removing the ones that are no longer connected. Good for checkbox UI or a tokenizer.
To answer your question, to find if a movie has a tag, you can do this
tag.in?(movie.tags)
And this is the way to add a single
movie.tags << tag unless tag.in?(movie.tags)
[EDIT]
If you do this
movie.update_attributes(movie_params)
and one of the params is the tag_ids, the movie will only save the new tags if it is valid (no other errors).
I believe there are 2 ways you can do this.
Check if #tagfound is included in #vid.tags
#vid.tags.include? #tagfound
Add the tag & call uniq after.
#vid.tags << #tagfound
#vid.tags.uniq!

Nil Values When Iterating Through Arrays and Some Really Weird Results

I'm a rails newbie and am building an app. My current problem is trying to find the average time since the last purchase for each customer of an online store using the app, where we have data about their orders and their customers. The problem is that I'm getting an error that says "undefined method `src_created_at' for nil:NilClass." Right now I'm trying to do this only for customers that have purchased once, and leaving aside those that purchased multiple times.
Here's my code:
#customers = Customer.where(:identity_id => #identity.id)
#single_order_customers = #customers.where("orders_count = ?", 1)
days_since_array = []
#single_order_customers.each do |s|
one_order = Order.where(:identity_id => #identity.id, :src_customer_id => s.src_id)
the_date = one_order[0].src_created_at
purchase_date = the_date.to_date
days_between = (Date.today - purchase_date)
days_since_array << days_between
end
days = days_since_array.inject(:+)
#adslp = days / days_since_array.count
Thanks in advance. I can provide what customer and order data looks like if necessary. Any advice would help, even though I know this question is somewhat vague. I've tried some kind if and unless statements validating presence or nil values and they're not working.
Edit:
Here's what's run in the console:
Order Load (123.0ms) SELECT "orders".* FROM "orders" WHERE "orders"."identity_id" = 2 AND "orders"."src_customer_id" = '114863554'
NoMethodError: undefined method `src_created_at' for nil:NilClass
(The above is several orders successfully run and then breaking on the last I've shown.)
Last point: when I try, specifically, to find nil values for this purpose I don't find any.
Order.where(:identity_id => 2, :src_created_at => nil)
Order Load (209.6ms) SELECT "orders".* FROM "orders" WHERE "orders"."identity_id" = 2 AND "orders"."src_created_at" IS NULL
=> []
For your last point where you tried to find nil values, you are getting an empty array [] because your query returned an empty set (no records matched your query). Trying to access any index on an empty array in rails won't throw an IndexOutOfBoundsException, but will instead just return nil, which is where you are getting your nil from. You are expecting one_order[0] to be an order item, but it is instead nil.
The solution to your problem would be to make sure the Order you are searching for already exists in the database. You might want to check how your orders are being created, e.g. if you use Order.create(params[:order]), do you have any validations that are failing, etc. You can check the orders you have through the rails console; just run Order.all. There should be an Order that has an identity_id of 2 and src_created_at of nil for the last query you wrote to return an actual order in the set.
A quick fix for now would be to remove the extra query to set one_order and just get it from the customer:
...
#single_order_customers.each do |s|
one_order = s.orders.first
the_date = one_order.src_created_at
...
The extra query does not seem to be necessary. You have already filtered #customers by identity_id, and src_customer_id will definitely match s.src_id if you get orders by calling s.orders. Relationships should be set up correctly in the models so that a customer has_many orders. You mentioned that you are just starting with rails; I would highly recommend reading a tutorial for rails first to save yourself headaches like these in the future :)

Creating Table Filters

I have a simple table with 3 columns like so
table
thead
th Element
th Owner
th Progress
tbody
== render :partial => "element_row" :collection => #elements :as => table_element
Each element is unique, and one owner may have several elements. There are a few different types of "progress" e.g. "started", "not started", and "completed".
I want to create a few links that filter the table. For example, I want to create an started link where when the user clicks on the link, the table is filtered down to only show rows where "started" is displayed. Another example of a filter is by owner.
Does anyone have any suggestions for how to do this?
If you're looking for a gem to help you, Ransack is a great, popular, and active project for searching (and by extension, filtering) ActiveRecord data.
If you check out Ernie's demo site you can see how the search parameters modify the URL through GET queries. You could easily create links like your desired started link to mock these GET form requests.
If you want to do this on the server side, add a filter method to the controller that uses link parameters to filter the #elements.
If you selecting #elements from the database using ActiveRecord, you could do:
#elements = Element.where(progress: params[:progress])
If you just want to filter the #elements in memory, you could do:
#elements = #elements.select{ |element| element.progress == params[:progress] }

How to get the previously related record?

I have a Feed model that looks like this:
Feed (id, project_id, content)
Given a Feed object like so (3031, 13, 'yada yo ya').
I want to find the Feed item, if any, that is before the feed object listed above. and it has to be for that project_id.
Something like, given #feed.project_id, find all Feed items for that project_id, and return the record previous to #feed = Feed.find(3031) if any.
Complicated right? Ideas?
Thanks.
You could run a query of all feeds for that project prior to the current feed and just pull the last record:
#feed = Feed.find(3031)
#previous_feed = Feed.where("id < ? and project_id = ?", #feed.id, #feed.project_id).order("id").last

Resources