Track Dates of viewed article - ruby-on-rails

I am working through my first Ruby on Rails App!
I have followed along with ruby's getting started tutorial and created a blog. http://guides.rubyonrails.org/getting_started.html
I am trying to implement a way to track when articles are viewed so I created a second table/model/controller that I'd like to insert the current date every time an article is viewed (show).
I'm not really sure how to implement this though... my initial though was in the article controller under the show def I would do something like
#view = View.new(view_params)
#view.Save!
This didn't really work. Any idea at all?
Thanks

You didn't mention what columns you had in your new model, but I'm assuming it's just the default timestamps and a field for the article ID.
So, within the 'show' action for the articles, you could do something like this. Your action names and such may differ, but the principle is the same.
def show
#article = Article.find(params[:id])
View.create(article_id:#article.id)
end
I can't think of any reason why you'd need to store the view itself in an instance variable, or any variable for that matter.

Related

How can I create a route and use a path to enter the first step in a mulistep form with the Wicked gem?

I have tried using the Wicked gem 3 different times over the past 8 years. Each time, I have given up for the same reason. I'm trying again, because if I understand it, I think it will be perfect for my use case.
My main problem is that I don't understand how to actually begin the wizard. With the example used in the gem, it is an after_registration event that already has an associated user object. That is not helpful, nor do I think that example would be helpful in the majority of use cases.
There is another example about building a Product in multiple steps. However, the author fails to adequately explain the routing. From https://github.com/zombocom/wicked/wiki/Building-Partial-Objects-Step-by-Step:
Since Wicked uses our :id parameter we will need to have a route that also includes :product_id for instance /products/:product_id/build/:id. This is one way to generate that route:
resources :products do
resources :build, controller: 'products/build'
end
This also means to get to the create action we don't have a product_id yet so we can either create this object in another controller and redirect to the wizard, or we can use a route with a placeholder product_id such as [POST] /products/building/build in order to hit this create action.
OK, I have no idea what the second part of the sentence means as far as placeholder product_id and that route name of /products/building/build. I spent 2 hours trying that and just moved on to a blank create form.
...we can either create this object in another controller and redirect to the wizard
That's what I'm trying to do upon successful save of the #product object.
redirect_to product_by_interchange_path(#product, :step1)
That doesn't work. raise InvalidStepError if the_step.nil? Says my step is nil. It's not.
redirect_to product_by_interchange_path(#product, step: :step1)
Same thing.
redirect_to product_by_interchange_path(:step1)
That's an exact mirror of the 8 year old example app. But of course #product isn't in a session variable like current_user is, so in this case the error is that there's no Product with an id of :step1.
Please help! I am missing something very, very basic here but I very much need to persist.
OK I have finally figured this out. Here's what I did:
First of all, I changed my controller back to a plain old ApplicationController and used the include include Wicked::Wizard. I don't know if that did anything, but the newer example was laid out like the old.
I was really screwed up by :id. I'm thinking :id is generally my object ID. I had a set_product private method in my controller, and it was failing. When I finally figured out that :id was the actual step itself, that led me to change my path in the redirect.
I changed the redirect from product_by_interchange_path(#product, :select_vehicle) to product_by_interchange_path(:select_vehicle, product_id: #product.id)
I got rid of my set_product. Just while I was trying to eliminate confusion.
I changed my finder calls in the wizard to use :product_id instead of :id.
It works now. I still don't understand how I could have stubbed out a route with a placeholder product_id, that's still a mystery. But this is fine and it works.

Unable to change the parameter from id to a custom variable in Rails

I've been racking my brain trying to figure out something that should be extremely simple, so I'm sure I'm just overlooking something and a fresh set of eyes might be useful since all my code is seemingly blurring together. I'm attempting to create vanity URLS for a site that allows users to create categories and then post relevant stories based on those categories. So, for example, I would like users to access /categories/movies in order to view the movie section. If I set it up to use the category id, /categories/1, it works no problem. For whatever reason, rails keeps trying to use the id parameter to find the category as opposed to the title parameter. I'm using Ruby 2.0.0 and Rails 4.0. I've read that the "find_by" method will become deprecated soon, so if there's a better way to handle this, that'd be great. Here's the relevant code:
Categories Controller
def show
#categories = Category.find_by_title(params[:title])
#category = Category.find_by_title(params[:title])
#posts = Post.where(category: set_category).all
end
Routes.rb
resources :categories
get "/categories/:title" => "categories#show"
Terminal readout when rendering page
Processing by CategoriesController#show as HTML
Parameters: {"id"=>"Movies"}
Just to reiterate, the parameters should read {"title"=>"Movies"} not id. Like I said, I'm sure it's something extremely simple that I've overlooked. Any help would be appreciated. Thanks.
I had to implement vanity urls as well and followed this blog post/tutorial
You pretty much create a slug in your model with the vanity-url, so
class Category < ActiveRecord::Base
def slug
title.downcase.gsub(" ", "-")
end
def to_param
"#{slug}"
end
end
Your show action in your controller would use the find_by_slug method
I think there is a gem that does this as well called friendly_id and here is a railscast but I have not personally used it
Hope this helps

Rails global variable

Im using bootstrap & rails and have a user model and post model..users create posts (collections)..
with bootstrap in the navbar i want the user to be able to click a dropdown which displays the name's of their posts..i did this on one controller with a private method and a before_action but i don't want to do this for all the controllers and it didn't work for the application controller...
is there a better way to do this??
I was doing this
def list
#user = User.find_by_username(params[:id])
#collections = #user.collections
end
and a
before_action :list
at the top of the controller
What's the most semantic way to accomplish this??
If you could move both to your application controller, then it would be available to any controller. More generally, I'm not sure if this is the best approach to solve your problem.
These tips might also be useful.
Are you using devise? Or some other authentication plugin? If so you're likely going to have a current_user helper. This would allow you to simply do #collections = current_user.collections
To the extent possible, I recommend using more descriptive names for your actions and parameters. def fetch_list_collections might be a better name or instead of passing a param named id, perhaps your param should be named username. These naming conventions become extremely important both for others who might look at your code as well as for yourself if you return to it and are trying to remember what you wrote N months ago.
Your list action is generating a N+1 queries. Meaning that you're hitting the database multiple times when you should do so just once. See the rails guide on this. You might also look at ways to avoid this w/ devise. Devise is pretty well documented and I'll bet there is something in the wiki discussing this.
You may want to consider limiting when you call this action - at a minimum - a post request to an update action? What about before they've logged in? current_user might be nil and you'd have an error attempting to call a collections method on nil.
Take your time learning this stuff. You don't have to learn it all at once, but I thought the above might be helpful.
I got it to work with this in the application controller
before_action :list
private
def list
#collections = current_user.collections
end
thanks #arieljuod

Searching based on field content - Ruby on Rails

So I am creating a ruby on rails application and in my view I have a list of link_to with each being a different console
In my database table I have a field called console.
What I want to do is when a user clicks on a link e.g. Playstation 3, it will return back all records that have Playstation 3 listed in that table column.
I was wondering how I would go about doing this, I have tried searching on the internet but have not found anything similar.
It is for a project that I don't have long to complete. I was owndering what I would state in the link to's in the view and what I would put in the games_controller.
Any help would be much appreciated.
The basic gist is to have a controller action which will return the list of games filtering by console. For example,
# GamesController.rb
def index
#games = Game.find_by_console(params[:console])
end
Then you can create a link for any particular console as such:
link_to 'XBOX', games_path(:console => 'XBOX')
This should result in a GET request to the URL /games?console=XBOX
If you've got a pre-defined set of consoles, you might look into making them into constants inside a Consoles module to avoid having to hardcode them everywhere.
UPDATE:
Since you are trying to implement both searching and filtering in the same chain, you need to make sure that find_by_console isn't called if it's not present.
# GamesController.rb
def index
#games = Game.search(params[:search])
#games = #games.find_by_console(params[:console]) unless params[:console].blank?
end

Ruby on Rails - enquiring about passing parameters

I am creating a simple RoR application where I can create posts and also comment on them. My thought on how to do this is to have posts and comments be of the same type and utilizing the same MVC except comments have a parent id. Posts will have a parent id of 0 while comments will have the id of its parents. I was thinking of when I tried to create a comment, I could just pass in the parent's id to the new method. This did not work. Although I got no errors it seems like the #post variable in the new method is not the same #post variable in the create method. My intuition was that the new method creates a new object then passes the object to the view. The view then populates the objects parameters and then sends it to the create method and the create method saves the object to the database. From trial and error this does not seem to be the case unless I am just doing it wrong. Is there an easier way to get the same functionality I am trying to achieve? or is there a way to get my way to work? any help would be greatly appreciated!
I would recommend you follow the classic "Build a Blog in 15 minutes" video that shows you how to do this.
Among other things, since a post has_many :comments I wouldn't recommend doing what you're proposing.

Resources