When I go through this with debugger, it does no hit the controller.
I get the following error:
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
i.e. #user is nil. #user is nil even if I set it to find the first one via #user = #Users.first
I want to access the user via domain.com/id
Routes.rb
match ':id' => 'user#show'
Model
class User < ActiveRecord::Base
attr_accessible :userLink, :userName
end
Controller controllers/user_controller.rb
def Show
#user= User.find_by_id params[:id]
# Attempted this with User.first to see if param was broken
respond_to do |format|
format.html
format.json { render json: #user}
end
end
View file name views/user/show.erb
<script type="text/javascript">
<%= #user.id %>
</script>
You have a typo.
def Show in your controllers should be def show
You don't need to specify route like this
Just replace this
match ':id' => 'user#show'
with
resources :users, only: [:show]
This will generate default route for you for show method
use
match '/:id' => 'user#show'
but this is not a good approach as many of your routes will be disabled by that
like if you have www.yourdomain.com/profile will also goes to your show action.
also def Show here Show should be show
Related
I am trying to create a button to change a model record attribute from false to true. I'm using a form_tag as follows:
=form_tag edit_goal_path(goal), method: :post do
=hidden_field_tag :purchased, value: true
=submit_tag "Purchase"
It's haml, but feel free to post suggestions with ERB. I'm getting the following error:
No route matches [POST] "/goals/4/edit"
Rails.root: /home/ben/rails_projects/hartwig
However, I already have the following route from resources:
PUT /goals/:id(.:format) goals#update
My controller looks as following:
def edit
#goal = Goal.find(params[:id])
end
def update
#goal = Goal.find(params[:id])
if #goal.update_attributes(goal_params)
redirect_to '/goals', notice: "Update successful!"
else
render '/'
end
end
def goal_params
params.require(:goal).permit(:item, :description, :picture, :purchased)
end
How do I get this to work? Or is there a better way to solve this?
Your question says:
I am trying to create a button to change a model record attribute from false to true
so why are you using a form for it? I think a better approach would be to create a link or button that will call an ajax method or a normal method with post route and update your attribute. You can achieve it by following these steps:
a. Create a route for your custom action where you'll update your attribute:
post 'purchase_update/:id' => "goal#update_purchase", as: update_purchase #post as you want to send your goal id
b. create your custom method inside your controller:
def update_purchase
#goal = Goal.find(params[:id])
#goal.update_attribute(:purchased, true)
respond_to do |format|
format.html {redirect_to your_path, notice: 'purchase updated'}
format.js {} #if you want to do something by ajax
end
end
c. Create your link that will call this method:
=link_to "Purchase", update_purchase_path(#goal), method: post
and if you want to do it by ajax then
=link_to "Purchase", update_purchase_path(#goal), method: post, remote: true
Another solution to your problem could be adding a new method to the Goal Controller:
in goals_controller.rb
def purchase
#goal.update_attribute(:purchased, true)
end
and also add on top (just add :purchase)
before_action :set_goal, only: [:show, :edit, :update, :destroy, :purchase]
in routes.rb change to
resources :goals do
member do
post 'purchase'
end
end
to add a new post routes to your goals
now you will have a purchase_goal_path that you can use in your view like this:
link_to 'Purchase', purchase_goal_path(#goal), method: :post
As i am new to rails, i cant pinpoint the error..
I am writing a method to get data by giving the only prod_id from the URL. I give the URL as localhost:3000/getproducts/PR1.josn to get the data in json format. But it shows an error that
ActiveRecord::RecordNotFound in GetproductsController#show
Couldn't find Product without an ID
Rails.root: /root/Railsapps/Shopping
Application Trace | Framework Trace | Full Trace
app/controllers/getproducts_controller.rb:12:in `show'
Here i am giving my getproducts.rb which is controller
class GetproductsController < ApplicationController
def index
#products = Product.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #products }
end
end
def show
#product = Product.find(params[:prod_id])
respond_to do|format|
format.html {render show.html.erb}
format.xml #{ render :xml => #product }
format.json {render json:#product}
end
end
end
My model is product.rb
class Product < ActiveRecord::Base
attr_accessible :model_name, :brand_name, :prod_id
end
my show.html.erb
<p id="notice"><%= notice %></p>
<p>
<b>Model Name:</b>
<%= #product.model_name %>
</p>
<p>
<b>Brand Name:</b>
<%= #product.brand_name %>
</p>
Could you also write the route that you have for that url in config/routes.rb?
On your model, you need to tell rails that your primary key is not "id" as expected, so do
class Product < ActiveRecord::Base
set_primary_key :prod_id
attr_accessible :model_name, :brand_name, :prod_id
end
Then you can do
Product.find(params[:id])
and it should work :)
I believe the problem is most likely that Rails is taking the parameter you provide and assuming that it's called id, so that when you ask for prod_id, there is no such parameter. This is the default for a show action - the parameter is assumed to be named id. You then try to find by params[:prod_id], which is nil, since params (probably) is just {:id => 'PR1'}.
You can fix this either by passing params[:id] instead of params[:prod_id] in your Product.find_by call, or by modifying your routes.rb file, thus:
resources :getproducts, :except => [:show]
get 'getproducts/:prod_id' => 'getproducts#show'
First, you tell Rails not to use the default show route for this controller (that's the :except option). Then, you define your own route, specifying the name of the parameter. This way, when you call getproducts/PR1, 'PR1' will get passed as params[:prod_id]. You need to exclude the default first because Rails will use the first route that matches, so as long as the default still exists, it's defined by the resources call.
When I create a user in my database, it also creates a unique identifier string.
In my routes, I have:
match '/users/:unique_identifer', :to => 'users#show'
This part is working fine. When I go to /users/xyz, it brings me to the show action for the appropriate user.
However, when I try to update the user record, it redirect me back to /users/SOMENUMBER where SOMENUMBER is the user's ID. This causes an error since the show action in the controller has:
def show
#user = User.find_by_unique_identifier(params[:unique_identifer])
end
In other words, the show action is now only looking up the user by their unique identifier and not the user id.
The update action is as follows:
def update
#user = User.find_by_unique_identifier(params[:unique_identifer])
if #user == current_user && #user.update_attributes(params[:user])
redirect_to #user
else
redirect_to #user
end
end
How do I get the update action to redirect to the user's show action but with the appropriate link (/users/unique_identifier) instead of /users/ID?
You should redefine to_param (and from_param to make life easier), it is used to generate links for objects, and by default use id field
so in your case
class User < ActiveRecord::Base
def to_param
unique_identifer
end
end
and now users_path(#user) should give you /users/your-uniq-identifier
here is nice description with examples:
http://apidock.com/rails/v3.1.0/ActiveRecord/Base/to_param
Try this
redirect_to user_path(#user.unique_identifer)
or
redirect_to :action => :show, :unique_identifer => #user.unique_identifer
Edit: i am using Mongoid/MongoDB for my database, meaning I don't get the normal Active Record tools I think.
I have a simple Rails 3.1 app with a model Page. I would like to match '/:customURL' to the Page#show action for the Page with the relevant :customURL. How should I change the controller and routes? Keep in mind that there are a few routes from '/SOMETHING' that I want to keep. For instance '/pages' should still go to my Page#index action not try to find a page with customURL of 'pages'.
current controller:
def show
#page = Page.find(params[:id])
#title = #page.title
respond_to do |format|
format.html # show.html.erb
format.json { render json: #page }
end
end
routes:
resources :pages do
resources :feeds
end
get "pages/index"
get "pages/show"
get "pages/new"
root :to => "pages#index"
Thanks a million.
Assuming that your Page has a customURL attribute from its database table. In your controller:
def show
#page = Page.first(:conditions => {:customURL => params[:customURL]})
#title = #page.title
respond_to do |format|
format.html # show.html.erb
format.json { render json: #page }
end
end
In your routes
resources :pages, :except => :show do
resources :feeds
end
# Anything you want to match before the custom URLs needs to go above the next route definition
get "/:customURL" => "pages#show"
root :to => "pages#index"
How do you use redirect_to when the Edit action is dependent on a parameter being passed?
I have two very simple actions edit and update. Once I click submit, following an update I'd like to redirect the user back to the edit action. How do I do this if the edit action requires a parameter?
def edit
#account = Account.find_by_user_id(#params['user_id'])
end
def update
account = Account.find(params[:account_user_id])
if account.update_attributes(params[:name])
redirect_to params[:user_id].merge!(:action => :edit)
else
render :text => 'Sorry there was an error updating.'
end
end
this code blows up
Try the following:
redirect_to edit_account_path( account.id, :user_id => params[:user_id])
I assume here you declared your routes as resources :accounts