Get routes from database in Rails - ruby-on-rails

How to load routes from database?
I have table Post with column :url. There is part of the url in this column, e.g.:
about
progs/us
progs/us/info
empty
etc.
How to set routes for this? Result example:
http://mysite.com/progs/us for the page http://mysite/posts/2

You can intercept any url by this route:
# routes.rb
get '*url' => 'posts#show', format: false
Note: this route should be declared last in your config
And controller looks like following:
# posts_controller.rb
class PostsController < ApplicationController
def show
#post = Post.find_by_url!(params[:url])
# by default "show" view is rendered with "post" variable
end
end

Here's how I made routes like this
www.example.com/jenny250
www.example.com/bob1985
At end of routes.rb
get ':username' => 'users#show'
In the users controller
def show
#user = User.find_by_username(params[:username])
# ...
end

Related

Rails Routing Precedence favors the first

So Ive been working on a rails project that defines two different create actions in the same controller. Here's my controller:
class SmsSendsController < ApplicationController
def new
#at = SmsSend.new
#contact = Contact.find_by(id: params[:id])
end
def create
#at = SmsSend.create(sms_params)
if #at.save!
#con = current_user.contacts.find_by(id: #at.contact_id)
AfricasTalkingGateway.new("trial-error").sendMessage(#con.phonenumber, #at.message)
end
end
def new_all
#at = SmsSend.new
#contact = Contact.find_by(id: params[:id])
end
def create_all
#at = SmsSend.create(sms_params)
if #at.save!
current_user.contacts.each do |c|
AfricasTalkingGateway.new("trial-error").sendMessage(c.phonenumber, #at.message)
end
end
end
private
def sms_params
params.require(:sms_send).permit(:mobile, :message, :contact_id)
end
end
In my
routes.rb
file, Ive used both custom and resourceful routes to define routes for the first and the second new/create actions:
Rails.application.routes.draw do
devise_for :users
get 'sms_sends/new_all', to: 'sms_sends#new_all'
post 'sms_sends', to: 'sms_sends#create_all'
resources :contacts
resources :sms_sends
root 'contacts#index'
end
So both post actions will work if and only if its routes are placed before the other. Is there a way I can get rid of the precedence? Or where am I going wrong?
Thankie.
So both post actions will work if and only if its routes are placed
before the other.
That is how you should define for the routes to work. Because the routes that defined in the routes.rb will be compiled from top-to-bottom. So if your custom routes gets preceded by resourceful routes, then the custom routes will conflict with your resourceful routes.
Is there a way I can get rid of the precedence?
Define them as collection routes like so,
resources :sms_sends do
get 'sms_sends/new_all', to: 'sms_sends#new_all', on: :collection
post 'sms_sends', to: 'sms_sends#create_all', on: :collection
end
The above will generate routes with path helpers like below
sms_sends_new_all_sms_sends GET /sms_sends/sms_sends/new_all(.:format) sms_sends#new_all
sms_sends_sms_sends POST /sms_sends/sms_sends(.:format) sms_sends#create_all
For a better readability, you can change your custom routes like so
resources :sms_sends do
get 'new_all', to: 'sms_sends#new_all', on: :collection
post 'create_all', to: 'sms_sends#create_all', on: :collection
end
This will generate the path helpers like below
new_all_sms_sends GET /sms_sends/new_all(.:format) sms_sends#new_all
create_all_sms_sends POST /sms_sends/create_all(.:format) sms_sends#create_all

static pages in rails app missing template

I have to add a static page to my rails app.
Here's the logic I am following.
I made a directory called pages and put a file called signup.html.erb there.
The path in my another html file is pages/signup
In my routes.rb, I have get 'pages/signup'
I made a pages controller and there I have something like below
class PagesController < ApplicationController
def signup
end
end
I get below error.
Missing template pages/signup, application/signup with
What's wrong here?
just write in routs.rb
get '/pages/signup', to: 'pages#signup'
and in pages_controller.rb write
def signup
#page = Page.new
end
def create
# write create function
end
In my routes.rb, try
get 'pages/signup'
match "signup", :to => "pages#signup"
on rails 4
get 'pages/signup'
match "signup", :to => "pages#signup", via: :all
Because your controller isn't in the spree namespace change the full path of the html file from
app/views/spree/pages/signup.html.erb
to
app/views/pages/signup.html.erb

No route matches [GET] "/"

I'm new to rails so it may sound quite naive.I'm getting this error
No route matches [GET] "/"
Here is my routes.rb
MyApp::Application.routes.draw do
match 'welcome/contact' => 'welcome#index'
end
Here is my controller
class WelcomeController < ApplicationController
def index
redirect_to :action => :contact
end
def contact
end
end
And i have a contact.html.erb in my app/view/welcome/.What am i doing wrong?
I don't understand what you want to do. But I think you want your view Welcome/contact as your index page, if this is correct, you only have to change your routes.rb file like this:
root to: 'welcome#contact'
and you have to remove the index.html file from the public folder.
On the other hand, you can read more of rails routes here
You need to create a route for the actions other than CRUD actions in controller.This will solve the issue for all actions.
match ':controller(/:action)'
What you want to do is to RENDER the contact page, not to redirect to another controller and action.
Just put the code in the contact view into the app/views/welcome/index.html.erb file, and live happily.
You need to add a contact action to your WelcomeController
class WelcomeController < ApplicationController
def index
redirect_to :action => :contact
end
def contact
end
end

How to handle multiple HTTP methods in the same Rails controller action

Let's say I want to support both GET and POST methods on the same URL. How would I go about handling that in a rails controller action?
You can check if it was a post using request.post?
if request.post?
#handle posts
else
#handle gets
end
To get your routes to work:
resources :photos do
member do
get 'preview'
post 'preview'
end
end
Here's another way. I included example code for responding with 405 for unsupported methods and showing supported methods when the OPTIONS method is used on the URL.
In app/controllers/foo/bar_controller.rb
before_action :verify_request_type
def my_action
case request.method_symbol
when :get
...
when :post
...
when :patch
...
when :options
# Header will contain a comma-separated list of methods that are supported for the resource.
headers['Access-Control-Allow-Methods'] = allowed_methods.map { |sym| sym.to_s.upcase }.join(', ')
head :ok
end
end
private
def verify_request_type
unless allowed_methods.include?(request.method_symbol)
head :method_not_allowed # 405
end
end
def allowed_methods
%i(get post patch options)
end
In config/routes.rb
match '/foo/bar', to: 'foo/bar#my_action', via: :all
Just need to use this, to use only get and post in the same route
resources :articles do
member do
match 'action_do-you_want', via: [:get, :post]
end
end
you can try this
match '/posts/multiple_action', to: 'posts#multiple_action', via: [:create, :patch, :get, :options]
I would say, the best way is to create separate actions in the controller and state them in routes.
# config/routes.rb
...
get '/my_action' => 'my#my_action_get'
post '/my_action' => 'my#my_action_post'
...
# app/controllers/my_controller.rb
...
def my_action_get
# do stuff like listing smth
end
def my_action_post
# do other stuff
end
In fact, the same logic is used by Rails by default: index and create actions are both called by requests sent to the same paths (e.g. /articles), however, they have different request methods: GET /articles request is redirected to the index action and lists all articles, and POST /articles is redirected to the create action and creates a new article.
This works for me:
In routes.rb
Rails.application.routes.draw do
post '/posts', to: 'posts#create'
get '/posts', to: 'posts#list_all'
end
In posts_controller.rb
class PostsController < ApplicationController
def create
new_post = Post.create( content: params[:content], user_id: params[:user_id] )
render json: { post: new_post }
end
def list_all
request = Post.all
render json: { all_posts: request }
end
end
So each action is referred to a different function

Rails 3 add GET action to RESTful controller

I have a controller with the 7 RESTful actions plus an additional 'current' action, which returns the first active foo record:
class FooController < ApplicationController
def current
#user = User.find(params[:user_id])
#foo = #user.foos.where(:active => true).first
#use the Show View
respond_to do |format|
format.html { render :template => '/foos/show' }
end
end
#RESTful actions
...
end
The Foo Model :belongs_to the User Model and the User Model :has_many Foos.
If I structure the routes as such:
resources :users do
resources :foos do
member do
get :current
end
end
end
The resulting route is '/users/:user_id/foos/:id'. I don't want to specify the foo :id, obviously.
I've also tried:
map.current_user_foo '/users/:user_id/current_foo', :controller => 'foos', :action => 'current'
resources :users do
resources :foos
end
The resulting route is more like I would expect: '/users/:user_id/current_foo'.
When I try to use this route, I get an error that reads:
ActiveRecord::RecordNotFound in FoosController#current
Couldn't find Foo without an ID
edit
When I move the current action to the application controller, everything works as expected. The named route must be conflicting with the resource routing.
/edit
What am I missing? Is there a better approach for the routing?
I think you want to define current on the collection, not the member (the member is what is adding the :id).
try this.
resources :users do
resources :foos do
collection do
get :current
end
end
end
Which should give you a route like this:
current_user_foos GET /users/:user_id/foos/current(.:format) {:controller=>"foos", :action=>"current"}
Also map isn't used anymore in the RC, it will give you a deprecation warning.

Resources