I am using the Public Activity Gem to track post for my app. Out of the box Public Activity gives me a ActivitiesController. I want to convert this controller to an API Controller so that I can make request to it from a mobile app. Below is the code I'm currently using. How can I rewrite the controller.
class ActivitiesController < ApplicationController
before_action :authenticate_user!
def index
#activities = PublicActivity::Activity.order("created_at desc")
end
end
class Api::V1::ActivitiesController < Api::BaseController
respond_to :json
def index
#activities = PublicActivity::Activity.order("created_at desc")
return render json: {message: "Activity Success"}
end
end
Rails.application.routes.draw do
namespace :api do
scope module: :v1 do
# devise_scope :api_v1_user do
resources :users, :only => [:show, :create, :update, :destroy]
# devise_for :users, :controllers => {passwords: 'api/v1/passwords'}
resources :activities, :only => [:index]
# end
end
end
Take a look here:
http://edgeguides.rubyonrails.org/api_app.html#creating-a-new-application
Focus on the "render json:" parts...
Related
I have been trying to add the name of the BlogCategory that a BlogPost belongs to in a URL such as this:
sitename.com/blog/category-name/blog-post-title
At the very least, I want this to render for the show of the BlogPost but am okay with it being the url for every action such as new, edit, and destroy.
I'm using the friendly_id gem, if that makes a difference.
BlogCategory Model:
class BlogCategory < ApplicationRecord
extend FriendlyId
friendly_id :name, use: :slugged
has_many :blog_posts
# This is a self referential relation. This is where records in a table may point to other records in the same table.
has_many :sub_categories, class_name: "BlogCategory", foreign_key: :parent_id
has_many :sub_category_blog_posts, through: :sub_categories, source: :blog_posts
belongs_to :parent, class_name: 'BlogCategory', foreign_key: :parent_id, optional: true
# This is a scope to load the top level categories and eager-load their posts, subcategories, and the subcategories' posts too.
scope :top_level, -> { where(parent_id: nil).includes :blog_posts, sub_categories: :blog_posts }
def should_generate_new_friendly_id?
slug.nil? || name_changed?
end
end
BlogCategory Controller:
class BlogCategoriesController < ApplicationController
before_action :admin_user, only: [:new, :create, :edit, :update, :destroy]
before_action :set_blog_link, only: [:show, :edit, :update, :destroy]
...
private
def cat_params
params.require(:blog_category).permit(:name, :parent_id, :sub_category, :summary)
end
def main_cat
#cat = BlogCategory.parent_id.nil?
end
def set_blog_link
#blog_link = BlogCategory.friendly.find(params[:id])
redirect_to action: action_name, id: #blog_link.friendly_id, status: 301 unless #blog_link.friendly_id == params[:id]
end
end
BlogPost Model:
class BlogPost < ApplicationRecord
extend FriendlyId
friendly_id :title, use: :history
belongs_to :blog_category
validates :title, presence: true, length: { minimum: 5 }
validates :summary, uniqueness: true
default_scope {order(created_at: :desc)}
def should_generate_new_friendly_id?
slug.nil? || title_changed?
end
end
BlogPost Controller:
class BlogPostsController < ApplicationController
before_action :admin_user, only: [:new, :create, :edit, :update, :destroy]
before_action :set_post_link, only: [:show, :edit, :update, :destroy]
before_action :find_post, only: :show
...
private
def post_params
params.require(:blog_post).permit(:title, :body, :summary, :thumbnail_link, :blog_category_id)
end
def find_post
#post = BlogPost.friendly.find(params[:id])
# If an old id or a numeric id was used to find the record, then
# the request path will not match the post_path, and we should do
# a 301 redirect that uses the current friendly id.
if request.path != blog_post_path(#post)
return redirect_to #post, :status => :moved_permanently
end
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
def set_post_link
#post_link = BlogPost.friendly.find(params[:id])
redirect_to action: action_name, id: #post_link.friendly_id, status: 301 unless #post_link.friendly_id == params[:id]
end
end
Here is relevant code from my routes.rb file:
Rails.application.routes.draw do
resources :blog_categories, path: 'blog'
resources :blog_posts
end
What I've tried
I've tried the following without success but have little understanding of what I'm doing:
get 'blog/:blog_category_name/:blog_post_title', to: 'blog_posts#show', as: 'blog_post'
and also tried
resources :blog_posts, path: 'blog/:blog_category_name/:blog_post_title', except: [:new, :create]
resources :blog_posts, only: [:new, :create]
With this in my BlogPost controller inside the show method/block:
#post_url = BlogPost.find_by(title: params[:blog_post_title], blog_category_id: params[:blog_category_name])
I even tried adding the params used in the routes to the permitted list under post_params.
I also tried making a new post to see if old posts weren't linking properly because of the url structure change.
The URL's I'm getting are not utilizing the parameters I'm passing to them.
What you're doing here is really just a nested resource but with a vanity route and and slugging which doesn't actually require such a heavy hand.
The typical controller for a nested resource would look like this:
class BlogPostsController < ApplicationController
before_action :set_blog_category
before_action :set_blog, only: [:show, :edit, :update, :delete]
# GET /blog/foo/bar - your custom vanity route
# the conventional route would be
# GET /blog_categories/foo/blog_posts/bar
def show
end
# GET /blog/foo/blogs_posts -> index
# GET /blog/foo/blogs_posts/new -> new
# POST /blog/foo/blogs_posts -> create
# ...
private
def set_blog_category
#blog_category = BlogCategory.friendly.find(params[:blog_category_id])
end
def set_blog
#blog = Blog.friendly.find(params[:id])
end
end
Besides the fact that you're using friendly.find you don't actually need to do anything to do the lookup via slugs instead of the id column. If you want to find the records only by their friendly id (and not allow numerical ids) use the find_by_friendly_id method instead.
Note that :id (or _id) in a parameter name is not equal to the id column - it's just a name for the unique indentifier segment in the URI pattern.
While you can configure the name of the param its actually kind of silly as in Rails things just work when you stick with the conventions.
You can just define the vanity route for this as:
resources :blog_categories, path: 'blog', only: [] do
# the typical routes nested under "blog_posts"
resources :blogs_posts, only: [:new, :create]
# your custom vanity route should be defined last to avoid conflicts
resources :blogs_posts, path: '/', only: :show
end
Generating the URL can be done either by calling the named blog_category_blog_path helper or by using the polymorphic route helpers:
blog_category_blog_path(#blog_category, #blog_post)
redirect_to [#blog_category, #blog_post]
form_with model: [#blog_category, #blog_post]
If you have legacy URLs using a different structure that you want to redirect I would consider using a separate controller or just doing the redirect in the routes to separate out the responsibilities from this controller.
You also should avoid duplicating the authorization/authentication logic across your controllers (your admin_user method). Thats how you get security holes.
I am trying to create a log out for my app and in my controller this piece of code is not working. Any solution would be helpful.
def destroy
#user = user.find(params[:id])
#user.destroy
end
This is my destroy method in my sessions controller(the fact that i am destroying my user in my sessions controller might be the problem)
class UsersController < ApplicationController
def new
end
def create
#user = User.create(password: params[:password],
email: params[:email],
firstname: params[:firstname],
lastname: params[:lastname])
redirect_to user_path(#user)
end
def show
#user = User.find(params[:id])
end
end
routes.rb:
Rails.application.routes.draw do
# Fubyonrails.org/routing.html
root :to => 'static#welcome'
resources :users, only: [:new, :create, :show]
resources :session, :only => [:new, :create, :destroy]
resources :studios
end
Routes file
uninitialized constant SessionController
is the error im getting
First, don't destroy your user. It deletes it from the database, you want them to be able to login again without creating a new user right?
You need to update your routes.rb file to be:
Rails.application.routes.draw do
# Fubyonrails.org/routing.html
root :to => 'static#welcome'
resources :users, only: [:new, :create, :show]
resources :sessions, :only => [:new, :create, :destroy] # changed to sessions
resources :studios
get 'logout' => 'sessions#destroy'
end
If you don't already, you need to define a SessionsController.
class SessionsController < ApplicationController
def destroy
# insert logic that actually logs them out, the below may already be enough
# for this purpose though
redirect_to root_url, notice: "Logged Out Successfully"
end
end
When the user clicks "Logout" it gets routed to the SessionsController#destroy action which redirects them to the root URL ('static#welcome')
There is more to it then that (i.e. the views and all that jazz) but this should be helpful enough
There is the following routing:
resources :accounts, only: [:update] do
get 'search', on: :collection
resources :transactions, only: [:create]
end
Abilities:
can [:update, :search], Account
can [:create, :index], Transaction
Controller:
# Web API controller for actions on Transaction
class Api::V1::Web::TransactionsController < Api::V1::Web::ApplicationController
load_and_authorize_resource :account
load_and_authorize_resource :transaction, through: :account
def create
render json: params and return
end
end
When I try to create a new transaction I get an error:
CanCan::AccessDenied
in Api::V1::Web::TransactionsController#create
What am I doing wrong? How can I fix it? Thanks in advance.
I'm trying to use the link_to helper function to create a new order for a particular product. Here is my:
product model
class Product < ActiveRecord::Base
has_many :orders
end
routes.rb
resources :products, :only => [:show, :new, :create, :index, :update, :destroy] do
resources :orders, :only => [:create]
end
view for product/show.html.erb
<%= link_to 'New Order', new_product_orders_path(#product) %>
controller for orders
class OrdersController < ApplicationController
def create
#order = Order.new
end
end
relevant rake routes:
product_orders POST /products/:product_id/orders(.:format) orders#create
But when I do that I get undefined method `new_product_orders_path'
Whats the correct way to do this in Rails 4?
In your routes add new action here
resources :orders, :only => [:create, :new]
Also your controller is missing new action, in your create action you need to save your record
class OrdersController < ApplicationController
before_filter :set_product
def new
#order = #product.orders.new
end
def create
#order = #product.orders.new(params[:order])
#order.save
end
private
def set_product
#product = Product.where("id =?", params[:product_id]).first
end
end
I think you need
resources :products, :only => [:show, :new, :create, :index, :update, :destroy] do
resources :orders, :only => [:create, :new]
end
You can also check your routes by typing '/rails/info/routes' at the end of your server path.
(I'm french)
I've a problem with my Rails (3.2.11) application. When i set my routes with some nouns, it doesn't work !
I explain:
Way::Application.routes.draw do
scope(:path_names => { :new => "nouveau", :edit => "edition" }) do
scope "/admin" do
resources :news, except: [:show, :index], path: '/articles'
resources :users, except: [:show]
resources :pages, except: [:show]
resources :events, except: [:show, :index]
resources :projects, except: [:show,:index], path: '/projets'
resources :galleries, except: [:index, :show] do
resources :paintings, except: [:index, :show]
end
end
end
end
The resources :projects doesn't work when i set it to "/projets".
What doesn't work is: when i want to create a new project in my form, i click on submit, it simply redirect me to "/projets", without doing something !
But when i set the route to "/poneys" for example, it works ! I really don't understand.
Thanks for your help.
https://github.com/khcr/way
class ProjectsController < ApplicationController
def new
#project = Project.new
render layout: 'admin'
end
def create
#project = Project.new(params[:project])
if #project.save
flash[:success] = "Projet créé"
redirect_to project_path(#project)
else
render 'new', layout: 'admin'
end
end
end