Can active record queries be used in controller action? - activerecord

I have a controller​ action which requires to find data from existing database. I am still learning rails and recently came to know about active record queries.
But I am not sure how to use it to fetch record from database in a controller action.
Can anybody please explain this with some example?
Thanks in advance

I found the answer. We can use active record queries to fetch the record from the database in the controller. Example is as follow:
Consider a database 'Dress' which has color attribute. Now I want to fetch all the 'dresses' which have orange color. So the query will be as:
#dresses = Dress.where(color: 'orange')
This will fetch all the record of dresses which have color = orange.

Yes you can used active record query inside controller. But better to put active record query logic inside model only. Because rails follow MVC Architecture
MVC stands for Model, View and Controller. MVC separates application into three components - Model, View and Controller.
Model: Model represents shape of the data and business logic. It maintains the data of the application. Model objects retrieve and store model state in a database. Model is a data and business logic.
View: View is a user interface. View display data using model to the user and also enables them to modify the data.
Controller: Controller handles the user request. Typically, user interact with View, which in-turn raises appropriate URL request, this request will be handled by a controller. The controller renders the appropriate view with the model data as a response.
Example:-
class RoomsController < ApplicationController
before_action :set_room, only: [:show, :edit, :update, :destroy]
# GET /rooms
# GET /rooms.json
def index
#rooms = Room.all
end
# GET /rooms/1
# GET /rooms/1.json
def show
end
# GET /rooms/new
def new
#room = Room.new
end
# GET /rooms/1/edit
def edit
end
# POST /rooms
# POST /rooms.json
def create
#room = Room.new(room_params)
respond_to do |format|
if #room.save
format.html { redirect_to #room, notice: 'Room was successfully created.' }
format.json { render :show, status: :created, location: #room }
else
format.html { render :new }
format.json { render json: #room.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /rooms/1
# PATCH/PUT /rooms/1.json
def update
respond_to do |format|
if #room.update(room_params)
format.html { redirect_to #room, notice: 'Room was successfully updated.' }
format.json { render :show, status: :ok, location: #room }
else
format.html { render :edit }
format.json { render json: #room.errors, status: :unprocessable_entity }
end
end
end
# DELETE /rooms/1
# DELETE /rooms/1.json
def destroy
#room.destroy
respond_to do |format|
format.html { redirect_to rooms_url, notice: 'Room was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_room
#room = Room.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def room_params
params.require(:room).permit(:name, :type, :user_id)
end
end

Related

Undefined Method 'add_product ' for model object

I think my error is kind of silly, but it's keeping me stuck. I'm following the Agile Web Development with Rails 4 and developing the app Depot from it. I'm getting a
undefined method `add_product' for #<Cart:0x007f2ee4cfb8f8>
error. My code is as follows,
class LineItemsController < ApplicationController
def create
find_cart
product = Product.find(params[:product_id])
byebug
#line_item = #cart.add_product(product.id) // line with error
#line_item.product = product
respond_to do |format|
if #line_item.save
format.html {redirect_to #line_item.cart,
notice: 'Line Item was succesfully created'}
format.json {render json: #line_item,
status: :created, location: #line_item}
else
format.html {render action: "new"}
format.json {render json: #line_item.errors,
status: "Unprocessable Entry"}
end
end
end
end
Cart.rb
class Cart < ActiveRecord::Base
has_many :line_items, dependent: :destroy
def add_products(product_id)
current_item = line_items.find_by_product_id(product_id)
if current_item
current_item.qunatity += 1
else
current_item = line_items.build(product_id: product_id)
end
current_item
end
end
Also, I want to know, how can a method from different model be directly called into a separate controller ?
The object cart has value, I have debugged to make sure, as well as the error line also has the object present.
Thanks for your help.
I found the mistake, it was a typo I made in Cart.rb. I had named the method add_product's' and was calling add_product in the controller.

State Machine Rails 4 doesn't back to the initial state

I need a little help with state machine because I'm working with rails 4 I have a initial state called in_analysis and other states called approved and reject and the states approved and reject works fine I don't have problem for pass through to the states, but I can't back to the initial state called in_analysis, here is my code:
app/models/profile.rb
state_machine :state, :initial => :in_analysis do
state :in_analysis, :approved, :rejected
state :approved do
validates :name, presence: true
end
event :approved do
transition in_analysis: :approved
end
event :reject do
transition in_analysis: :rejected
transition approved: :rejected
end
end
and in my controller I have this:
def update
#profile.state = :in_analysis
#profile = current_user.profile
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to edit_profile_path(#profile), notice: t(:update, scope: [:messages, :controllers, :profiles, :successfully]) }
format.json { render :show, status: :ok, location: edit_profile_path(#profile) }
else
format.html { render :edit }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
so my goal is when the profile is updated the state back to the initial "in_analysis" but I don't know why doesn't work because the another state works well.
Thanks for the time ! regards !
Assuming that your state_machine is correct, the only place that you might be doing wrong is
#profile.state = :in_analysis
#profile = current_user.profile
You assign the state to :in_analysis then you actually assign #profile to old current_user.profile which is fetched from database thus your assignment to :in_analysis is discarded.
You can try to swap the two line:
#profile = current_user.profile
#profile.state = :in_analysis

Rails (One Month Rails) NoMethodError in PinsController#create

Problem solved thanks to #skipchris (https://twitter.com/skipchris) Using debugger we found a spelling mistake. The error report didn't make much sense but i learned plenty investigating the problem!
I've spent last night and this morning trying to find a solution but i'm new to rails. From what i've read so far it think the problem is to do with association. I created a Pin without a User (association error?) and so there is an error with routing i.e something to do with Devise?
When i try to create a new Pin i get this error in browser on my local server-
NoMethodError in PinsController#create
pp/controllers/pins_controller.rb:48:in block in create'
app/controllers/pins_controller.rb:47:increate'
pins_controller.rb
def create
#pin = current_user.pins.new(params[:pin])
respond_to do |format|
if #pin.save
format.html { redirect_to #pin, notice: 'Pin was successfully created.' }
format.json { render json: #pin, status: :created, location: #pin }
else
format.html { render action: "new" }
format.json { render json: #pin.errors, status: :unprocessable_entity }
end
end
end
User Model (user.rb)
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, #:recoverable,
:rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation,
:remember_me, :name
has_many :pins
end
Yeah, I would definitely make a user model since you are trying to access current_user.pins in the methods. also do you have
resources :pins
or something similar in your routes?

How to build a preference record associated with a user in Ruby on Rails?

In Ruby on Rails, when a new user is created I want to automatically create an associated preference record to that user.
This is my controller:
class UsersController < ApplicationController
def create
#user = User.new(params[:user])
if #user.save
#user.build_preference
redirect_to root_path, :notice => "User created."
else
render :new
end
end
end
However, for some reason I can't get this to work. The user gets saved successfully but when I check the database there is no related preference record.
What am I missing here?
Is it better to create the associated record from within the model using :before_create or something?
Thanks for any help.
You need to save:
def create
#user = User.new(params[:user])
if #user.save
pr = #user.build_preference
pr.save!
redirect_to root_path, :notice => "User created."
else
render :new
end
end

Rails Find with Active Resource Ignoring Parameters

I have two Rails apps, one client using ActiveResource and one service. I am testing the following command via the console:
User.find(:all, :params => {:email_address => "myemail#domain.com"})
I get back all the records in my user table and not just the one specified in my email parameter.
When I go look at the log for my service app it shows as follows
Started GET "/users.json?email_address=myemail%40domain.com" for 127.0.0.1 at 2011-12-29 11:29:06 -0600
(0.4ms) SHOW search_path
Processing by UsersController#index as JSON
Parameters: {"email_address"=>"myemail#domain.com"}
User Load (0.7ms) SELECT "users".* FROM "users"
Completed 200 OK in 40ms (Views: 35.7ms | ActiveRecord: 3.3ms)
My parameter was not included in the SQL statement.
Any insight?
Based on your comment on the original question, your controller still looks like this:
class UsersController < ActionController::Base
def index
#users = User.all
respond_to do |format|
format.json { render json: #users }
end
end
#other methods down here
end
But in order to get your index view to render just the ones that match the email, you need to update the index method to:
class UsersController < ActionController::Base
def index
#users = User.find_all_by_email_address(email_address)
respond_to do |format|
format.json { render json: #users }
end
end
#other methods down here
end
Conditions are passed to ActiveRecord find method via :conditions option and not :params. So your find call should be like that:
User.find(:all, :conditions => { :email_address => "myemail#domain.com" })
or in more Rails 3 style:
User.where(:email_address => "myemail#domain.com").all
You can find full list of available parameters for find method in docs.

Resources