Setting rails routes to url path - ruby-on-rails

I'm new to rails and having problems with my routes. When a link gets submitted, it should go to 'http://example.com' although it now goes to localhost:3000/links/www.example.com
I am running ruby 3.2.8 and ruby1.9.3p194. Not sure how much info is needed. Here's where it's at.
In my view I have:
<p>
<h1><%= #link.title %></h1>
<%= link_to #link.url, #link.url %><br />
<p>Posted by: <% #link.user %> at <%= #link.created_at %></p>
</p>
My controller is set as:
class LinksController < ApplicationController
def show
#link = Link.find(params[:id])
end
before_filter :authenticate_user!
def new
#link = Link.new
end
def create
#link = Link.new(params[:link])
respond_to do |format|
if #link.save
format.html { redirect_to #link, notice: 'Link was successfully created.' }
format.json { render :json => #link, status: :created, location: #link }
else
format.html { render :action => "new" }
format.json { render :json => #link.errors, :status => :unprocessable_entity }
end
end
end
end
In my development.rb file I have:
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
And my routes are:
resources :pages
resources :links
root :to => "pages#index"
After countless searches, I've had no luck since I am a beginner. Any suggestions for how to reset the link paths greatly appreciated.

There is nothing to do with routes or Rails here.
You need to output http:// in front of your links, if you want to link off-site. Either enter in in the textbox when you submit your link, or modify your code to conditionally prepend it:
<% link_href = #link.url %>
<% link_href = "http://#{link_href}" unless link_href.match(/^https?:\/\//) %>
<%= link_to #link.url, link_href %><br />

Related

Rails 4.0 ActiveRecord::RecordNotFound

I am trying to learn Rails and am making my first app and am running into this error:
ActiveRecord::RecordNotFound in PartsController#show
Couldn't find Part with id=new_ic
with the highlighted source:
def set_part
#part = Part.find(params[:id])
end
I am brand new to rails and i can't figure out what is wrong and I can't find any help online either. The app is a part management system for electronic components. The form gets filled out and the data is saved to the database for future reference/updating. Could someone please help?
Source code time:
parts/_ic_form.html.erb
<h1>Add An IC</h1>
<%= simple_form_for #parts do |f| %>
<%= f.input :component_type, :as => :hidden, :input_html => { :value => "IC"} %>
<%= f.input :ic_model, label: 'IC Model' %>
<%= f.input :ic_manufacturer, label: 'IC Manufacturer' %>
<%= f.input :ic_pinCount, label: 'IC Pin-Count' %>
<%= f.input :ic_mountType, collection: ["Through Hole", "Surface Mount"], label: 'IC Mount Type' %>
<%= f.input :ic_package, label: 'IC Package' %>
<%= f.input :ic_quantityOnHand, label: 'Quantity On Hand' %>
<%= f.input :ic_quantityOnOrder, label: 'Quantity On Order' %>
<%= f.button :submit %>
<% end %>
parts/new_ic.html.erb
<%= render 'ic_form' %>
parts/new.html.erb
<h1>New part</h1>
<%= link_to 'IC', 'new_ic' %>
<%= link_to 'Back', parts_path %>
parts_controller.rb
class PartsController < ApplicationController
before_action :set_part, only: [:show, :edit, :update, :destroy]
before_filter :initialize_parts
def initialize_parts
#parts = Part.new
end
# GET /parts
# GET /parts.json
def index
#parts = Part.all
end
# GET /parts/1
# GET /parts/1.json
def show
end
# GET /parts/new
def new
#part = Part.new
end
# GET /parts/1/edit
def edit
end
# POST /parts
# POST /parts.json
def create
#part = Part.new(part_params)
respond_to do |format|
if #part.save
format.html { redirect_to #part, notice: 'Part was successfully created.' }
format.json { render action: 'show', status: :created, location: #part }
else
format.html { render action: 'new' }
format.json { render json: #part.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /parts/1
# PATCH/PUT /parts/1.json
def update
respond_to do |format|
if #part.update(part_params)
format.html { redirect_to #part, notice: 'Part was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #part.errors, status: :unprocessable_entity }
end
end
end
# DELETE /parts/1
# DELETE /parts/1.json
def destroy
#part.destroy
respond_to do |format|
format.html { redirect_to parts_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_part
#part = Part.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def part_params
params[:part]
end
end
routes.rb Pretty sure i screwed this one up too
Pms::Application.routes.draw do
resources :parts
resources :parts
root to: "parts#new_ic"
end
rake routes Output:
Prefix Verb URI Pattern Controller#Action
parts GET /parts(.:format) parts#index
POST /parts(.:format) parts#create
new_part GET /parts/new(.:format) parts#new
edit_part GET /parts/:id/edit(.:format) parts#edit
part GET /parts/:id(.:format) parts#show
PATCH /parts/:id(.:format) parts#update
PUT /parts/:id(.:format) parts#update
DELETE /parts/:id(.:format) parts#destroy
GET /parts(.:format) parts#index
POST /parts(.:format) parts#create
GET /parts/new(.:format) parts#new
GET /parts/:id/edit(.:format) parts#edit
GET /parts/:id(.:format) parts#show
PATCH /parts/:id(.:format) parts#update
PUT /parts/:id(.:format) parts#update
DELETE /parts/:id(.:format) parts#destroy
root GET / parts#new_ic
One problem is in this line:
<%= link_to 'IC', 'new_ic' %>
link_to should look like this:
link_to "Profile", profile_path(#profile)
#Profile is the name
#profile_path(#profile) is the link
Try this instead:
#parts/new.html.erb
<%= link_to 'IC', root_path %>
in your routes, root GET / parts#new_ic is linking to your new_ic action. I'd disagree with the way you access it (via root) - but it will work if you want to access the new_ic action. Why is this your root route, though?

how to enable only authenticated users to create new users

I guess the title is self explanatory...how do I make only authenticated users to create a user with devise?
when I try to add a new one (when authenticated), devise says that I'm alreade authenticated
any workaround for this?
thanks a lot
edit: as requested, my code
user form
<% if #user == current_user %>
<i class="icon-info-sign"> </i><i>Após alterar seus dados, você terá de fazer login novamente</i>
<% end %>
<%= form_for(#user, :html => { :class => "well form-horizontal"}) do |f| %>
<% if #user.errors.any? %>
<div class="alert alert-error">
<h2><%= pluralize(#user.errors.count, "erro") %>
<% if #user.errors.count == 1 %> impede
<% else %>
impedem
<% end %>
a continuação:</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<label>Nome</label><%= f.text_field :nome %>
<label>E-mail</label><%= f.email_field :email %>
<% if #user == current_user or #user.created_at == nil%>
<label>Senha</label><%= f.password_field :password %>
<% end %>
<div>
<br />
<button class="btn" type="submit">
Salvar alterações
</button>
</div>
<% end %>
part of users controller
before_filter :authenticate_user!
def index
#users = User.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #users }
end
end
# GET /users/1
# GET /users/1.json
def show
#user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #user }
end
end
# GET /users/new
# GET /users/new.json
def new
#user = User.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #user }
end
end
# GET /users/1/edit
def edit
#user = User.find(params[:id])
end
# POST /users
# POST /users.json
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
format.html { redirect_to #user, notice: 'User was successfully created.' }
format.json { render json: #user, status: :created, location: #user }
else
format.html { render action: "new" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
# PUT /users/1
# PUT /users/1.json
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
format.html { redirect_to #user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
application controller
class ApplicationController < ActionController::Base
protect_from_forgery
def after_sign_in_path_for(resource)
return request.env['omniauth.origin'] || stored_location_for(resource) || painel_path
end
end
part of routes
App::Application.routes.draw do
resources :acampantes
devise_for :users, :skip => [:registrations]
resources :profiles
resources :eventos do
resources :acampantes
end
# aqui tem um has_many, mas não precisa de nested routes
resources :noticias
resources :users#, :as => "usuarios"
The ideal way to do it would be to override registrations_controller.rb (as shown here) and skipping the before_filter check for the new and create action. I tried to do it myself, but unfortunately, I couldn't get it right.
Another way to do it, which worked for me, would be to create a separate User controller aside from the Registrations controller provided by Devise:
class UsersController < ApplicationController
before_filter :authenticate_user!
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
flash[:success] = "User saved"
redirect_to #user
else
render 'new'
end
end
end
# routes.rb
ApplicationName::Application.routes.draw do
devise_for :users
resources :users, :only => [:new, :create]
end
Then make a form for the new action:
# app/views/users/new.html.erb
<%= form_for(#user) do |f| %>
<div><%= f.label :email %><br />
<%= f.email_field :email %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<div><%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation %></div>
<div><%= f.submit "Sign up" %></div>
<% end %>
The problem with this approach is that the routes provided by Devise for signing-up still exists. A solution for that would be to prevent Devise from generating routes involving registration:
# routes.rb
devise_for :users, :skip => [:registrations]
This means that you are going to ignore the Registrations module completely and make your own. I got this idea from the Bare-bone, stripped-down Devise tutorial. Take note that you should make the controller actions and views to replace the ones provided by the registrations module of Devise. This includes new, edit, create, update, and destroy.

Simple one model singular resource routing problem

I have a stripped down shopping cart application, currently with one model "cart", the cart id is stored in a session.
the cart controller has this method so we always have a cart
def initialize_cart
if session[:cart_id]
#cart = Cart.find(session[:cart_id])
else
#cart = Cart.create
session[:cart_id] = #cart.id
end
end
my routes file has this one line
map.resource :cart
my cart/show view looks like this, i have added a form to it so that ultimately i can update the quantity of items, but for now i am just editing the created_at attribute.
<% form_for(#cart) do |f| %>
<%= f.date_select :created_at %>
<p>
<%= f.submit 'Update' %>
</p>
<% end %>
<%= link_to 'Edit', edit_cart_path(#cart) %> |
<%= link_to 'Back', cart_path %>
and finally, my update action looks like this:
def update
##cart = Cart.find(params[:id])
respond_to do |format|
if #cart.update_attributes(params[:cart])
format.html { redirect_to(cart_path) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #cart.errors, :status => :unprocessable_entity }
end
end
end
when i make a change to "created_at" attribute on the "show" page, the attribute is successfully updated, but when i get redirected, i get a bizare url like this
http://192.168.0.10:3000/cart.%23%3Ccart:0x23d46fc%3E
I have fiddled with the update action, and can get the whole thing to work perfectly by doing this
# PUT /carts/1
# PUT /carts/1.xml
def update
##cart = Cart.find(params[:id])
#respond_to do |format|
if #cart.update_attributes(params[:cart])
redirect_to(cart_path)
# head :ok
#else
# render :action => "edit"
# render :xml => #cart.errors, :status => :unprocessable_entity }
end
#end
Its something to do with the respond_to block that is causing it to mess up, i would really appreciate any help i can get with this.
Thanks
For singular resource, you don't need to specify the object in the routes.
So you should use this:
<%= link_to 'Edit', edit_cart_path %>
===== UPDATED =====
I just found your real problem ^^" (but the original should be true too)
You used form_for(#cart) do |f|, which produced that ugly path
Please change to form_for(#cart, :url => cart_path) do |f|
I don't know why too, but it should be ok......

PUT-ing a form to update a row, but I can't find the id. Where is it?

How should I be passing in the ID?
Error:
Couldn't find Product without an ID
Form:
<% form_for :product, #product, :url => { :action => :update } do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :names %><br />
<%= f.text_field :names %>
</p>
<p>
<%= f.submit 'Update' %>
</p>
<% end %>
Controller (for /products/edit/1 view):
def edit
#product = Product.find(params[:id])
end
Controller (to change the db):
def update
#product = Product.find(params[:id])
respond_to do |format|
if #product.update_attributes(params[:product])
format.html { redirect_to(#product, :notice => 'Product was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #product.errors, :status => :unprocessable_entity }
end
end
end
Try removing the :product from the form_for statement
Edit: Try removing the url option also. The issue is that the URL which you are posting to does not have an id attribute.
This form tag should be sufficent:
<% form_for #product do |f| %>
Make sure you have this line in your config/routes.rb:
map.resources :products
For extra credit, you can simplify loading the #product in your controller with a before_filter:
class ProductsController < ApplicationController
before_filter :load_product, :only => [:show, :edit, :update, :destroy]
def load_product
#product = Product.find(params[:id])
end
end

Adding my comments to the index view...Ruby on Rails

Ok...I am new to rails so this may be a stupid question but need help. I just watched and implemented Ryan Bates screencaset about setting up a blog. You can see it here http://media.rubyonrails.org/video/rails_blog_2.mov. Here is the skinny:
Two tables: Posts and Comments. Everything works great including the addition of comments via AJAX. The default development of this blog gives you the index.html.erb view where you can view all the posts
def index
#posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
format.json { render :json => #posts }
format.atom
end
end
The comments are only viewed via the show.html.erb page and is displayed via this code in that file:
<%= render :partial => #post %>
<p>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%= link_to 'Destroy', #post, :method => :delete, :confirm => "Are You Sure" %> |
<%= link_to 'See All Posts', posts_path %>
</p>
<h2>Comments</h2>
<div id="comments">
<%= render :partial => #post.comments %>
</div>
<% remote_form_for [#post, Comment.new] do |f| %>
<p>
<%= f.label :body, "New Comment" %><br/>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Add Comment"%></p>
<% end %>
What I am trying to do is to get similair representation of the comments functionality to exist in the index.html.erb view (which I will hide with javascript). Which currently just looks like this:
<h1>Listing posts</h1>
<%= render :partial => #posts %>
<%= link_to 'New post', new_post_path %>
My initial thought was just to put this exact same code that is in the show.html.erb file in the index.html.erb file but that doesn't work. I have tried a bunch of things here but I am not familiar enough with Rails (or coding for that matter) yet to do this in a timely manner. I get two main errors. Either that I passed a nil.comments error or an undefined object/method (can't remember).
My question is what do I need to included in the post_controller, the comments_controller and the index.html.erb file to accomplish this. To be complete I have included the code in each below.
POSTS_CONTROLLER
class PostsController < ApplicationController
before_filter :authenticate, :except => [:index, :show]
# GET /posts
# GET /posts.xml
def index
#posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
format.json { render :json => #posts }
format.atom
end
end
# GET /posts/1
# GET /posts/1.xml
def show
#post = Post.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/new
# GET /posts/new.xml
def new
#post = Post.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #post }
end
end
# GET /posts/1/edit
def edit
#post = Post.find(params[:id])
end
# POST /posts
# POST /posts.xml
def create
#post = Post.new(params[:post])
respond_to do |format|
if #post.save
flash[:notice] = 'Post was successfully created.'
format.html { redirect_to(#post) }
format.xml { render :xml => #post, :status => :created, :location => #post }
else
format.html { render :action => "new" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# PUT /posts/1
# PUT /posts/1.xml
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
flash[:notice] = 'Post was successfully updated.'
format.html { redirect_to(#post) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.xml
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to(posts_url) }
format.xml { head :ok }
end
end
private
def authenticate
authenticate_or_request_with_http_basic do |name, password|
name == "admin" && password == "secret"
end
end
end
COMMENTS_CONTROLLER
class CommentsController < ApplicationController
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create!(params[:comment])
respond_to do |format|
format.html { redirect_to #post}
format.js
end
end
end
INDEX.HTML.ERB
<h1>Listing posts</h1>
<%= render :partial => #posts %>
<%= link_to 'New post', new_post_path %>
Here's one simple solution. Step 1, edit your index action to include all the comments belonging to each post.
def index
#posts = Post.all(:include => :comments)
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => #posts }
format.json { render :json => #posts }
format.atom
end
end
Step 2, edit your index view to display each post, followed by its comments:
<h1>Listing posts</h1>
<% #posts.each do |post| %>
<%= render :partial => post %>
<%= render :partial => post.comments %>
<% end %>
<%= link_to 'New post', new_post_path %>
Edit: I'm not 100% sure of the best way to include the comment creation form also. What I'd try first is this (in index.html.erb):
Try changing your index view to:
<h1>Listing posts</h1>
<% #posts.each do |post| %>
<%= render :partial => post %>
<%= render :partial => post.comments %>
<% remote_form_for [post, Comment.new] do |f| %>
<p>
<%= f.label :body, "New Comment" %><br/>
<%= f.text_area :body %>
</p>
<p><%= f.submit "Add Comment"%></p>
<% end %>
<% end %>
<%= link_to 'New post', new_post_path %>
This should render the "New comment" form for a given post under the comments for that post, but I'm not sure (without actually trying it out) whether the form submission AJAX will successfully update and refresh the index page.

Resources