i've been starting to learn rails and ruby. Im coding and app that one user has many buys and sell. I've been doing all the tutorials and looking for many answers here in SOF but without success so this is my issue:
NoMethodError in SellsController#create
undefined method `sell' for #
Where my user is "usuario" in spanish.
I know im missing something in somewhere because i already do this with the buys and works good. These are my files
Usuario.rb (Model)
class Usuario < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :sells
has_many :buys
end
There is the "Has_many"
Sell.rb (Model)
class Sell < ActiveRecord::Base
belongs_to :usuario
after_create :set_estado
private
def set_estado
self.estado = true
end
end
That method is because Im trying to set the "estado" (Status) as true.
Sells Controller
class SellsController < ApplicationController
before_action :set_sell, only: [:show, :edit, :update, :destroy]
before_action :authenticate_usuario!
# GET /sells
# GET /sells.json
def index
#sells = Sell.all
end
# GET /sells/1
# GET /sells/1.json
def show
end
# GET /sells/new
def new
#sell = Sell.new
end
# GET /sells/1/edit
def edit
end
# POST /sells
# POST /sells.json
def create
#sell = current_usuario.sell.new(sell_params)
respond_to do |format|
if #sell.save
format.html { redirect_to #sell, notice: 'La venta ha sido creada con exito' }
format.json { render :show, status: :created, location: #sell }
else
format.html { render :new }
format.json { render json: #sell.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /sells/1
# PATCH/PUT /sells/1.json
def update
respond_to do |format|
if #sell.update(sell_params)
format.html { redirect_to #sell, notice: 'La venta ha sido modificada con exito.' }
format.json { render :show, status: :ok, location: #sell }
else
format.html { render :edit }
format.json { render json: #sell.errors, status: :unprocessable_entity }
end
end
end
# DELETE /sells/1
# DELETE /sells/1.json
def destroy
#sell.destroy
respond_to do |format|
format.html { redirect_to sells_url, notice: 'La venta ha sido eliminada con exito.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_sell
#sell = Sell.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def sell_params
params.require(:sell).permit(:usuario_id, :fecha_compra, :peso_final, :monto, :estado, :cantidad)
end
end
Im using scaffolds and the gem devise for authenticate.
I don't know what im missing because i have almost the same thing in buys and it's working but for sells doesnt work :(
My Routes.db
Rails.application.routes.draw do
devise_for :usuarios
devise_for :users
resources :usuarios do
resources :buys
resources :sells
end
get 'welcome/index'
post 'welcome/index'
post 'users/index'
resources :buys
resources :users
resources :sells
end
This is my first app on rails so i dont know what i missing now. Im using devise,Rails 4.2.1 and postgre as database
If your association is a has_many, Rails will use the plural form of the model as the association name. So instead of
current_usario.sell.new
try:
current_usario.sells.build
If you only expect one Sell per user, use a has_one association instead.
P.S. You might consider using "sales" instead of "sells", and "purchases" instead of "buys".
Related
I'm completely new to Ruby on Rails and I'm stuck with giving specific roles permissions. I created 8 different roles with an enum. 2 of them should be allowed to create some "cases". How can I implement that? Maybe someone can help me? Is giving permission the right way?
PS: I'm using Rails 6.0.3.4.
Here my code:
Cases Controller:
class CasesController < ApplicationController
before_action :set_case, only: [:show, :edit, :update, :destroy]
# GET /cases
# GET /cases.json
def index
#cases = Case.all
end
# GET /cases/1
# GET /cases/1.json
def show
end
# GET /cases/new
def new
#case = Case.new
end
# GET /cases/1/edit
def edit
end
# POST /cases
# POST /cases.json
def create
#case = Case.new(case_params)
respond_to do |format|
if #case.save
format.html { redirect_to #case, notice: 'Case was successfully created.' }
format.json { render :show, status: :created, location: #case }
else
format.html { render :new }
format.json { render json: #case.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /cases/1
# PATCH/PUT /cases/1.json
def update
respond_to do |format|
if #case.update(case_params)
format.html { redirect_to #case, notice: 'Case was successfully updated.' }
format.json { render :show, status: :ok, location: #case }
else
format.html { render :edit }
format.json { render json: #case.errors, status: :unprocessable_entity }
end
end
end
# DELETE /cases/1
# DELETE /cases/1.json
def destroy
#case.destroy
respond_to do |format|
format.html { redirect_to cases_url, notice: 'Case was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_case
#case = Case.find(params[:id])
end
# Only allow a list of trusted parameters through.
def case_params
params.require(:case).permit(:first_name, :last_name, :gender, :birthdate, :place_of_residence, :diagnosis, :user_id, :confirmed_at)
end
end
Application Controler:
class ApplicationController < ActionController::Base
before_action :authenticate_user!
end
User.rb
class User < ApplicationRecord
enum role: [:user, :vip, :admin, :arzt, :labor, :ga, :ls, :rki]
after_initialize :set_default_role, if: :new_record?
def set_default_role
self.role ||= :user
end
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
end
Simplest solution might be a before action...
CasesController << ApplicationController
before_action :allowed_to_create, only: [:new, :create]
private
def allowed_to_create
unless current_user.role.in?(['type1', 'type2'])
flash[:error] = 'You are not allowed to do that'
redirect_to root_path
end
end
end
If your permmissions are likely to be more complex, take a look at the cancancan gem.
notes use rails 5.2 and postgresql
I have Foluser model contains name,email,password,id_watch
I need when admin add new foluser
generate password
when admin create new foluser generate password like Secure Password Generator
get id_watch from admin model and put it to id_watch from Foluser model
Adminwhen register enterusername,email,password,id_watch`
in point 2 need take this id_watch and save it in user model .
admin only create foluser
`
class FolusersController < ApplicationController
before_action :set_foluser, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!, except: [:index, :show, :new , :create, :edit]
# GET /folusers
# GET /folusers.json
def index
#folusers = current_master.foluser.all
#render json: #folusers
end
# GET /folusers/1
# GET /folusers/1.json
def show
##folusers = Foluser.where(master_id: #master.id).order("created_at DESC")
##foluser = Foluser.find(params[:id])
#render json: #foluser
end
# GET /folusers/new
def new
#foluser = current_master.foluser.build
end
# GET /folusers/1/edit
def edit
#render json: #foluser
end
# POST /folusers
# POST /folusers.json
def create
#foluser = current_master.foluser.build(foluser_params)
respond_to do |format|
if #foluser.save
format.html { redirect_to #foluser, notice: 'Foluser was successfully created.' }
format.json { render :show, status: :created, location: #foluser }
else
format.html { render :new }
format.json { render json: #foluser.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /folusers/1
# PATCH/PUT /folusers/1.json
def update
respond_to do |format|
if #foluser.update(foluser_params)
format.html { redirect_to #foluser, notice: 'Foluser was successfully updated.' }
format.json { render :show, status: :ok, location: #foluser }
else
format.html { render :edit }
format.json { render json: #foluser.errors, status: :unprocessable_entity }
end
end
end
# DELETE /folusers/1
# DELETE /folusers/1.json
def destroy
#foluser.destroy
respond_to do |format|
format.html { redirect_to folusers_url, notice: 'Foluser was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_foluser
#foluser = Foluser.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def foluser_params
params.require(:foluser).permit(:name, :email, :numberphone, :password)
end
end
foluser model
class Foluser < ApplicationRecord
belongs_to :admin, :optional => true
end
admin model
class Master < ApplicationRecord
has_many :foluser
end
Using your current code, setting the id_watch can be done here in the controller:
class FolusersController < ApplicationController
def create
#foluser = current_master.folusers.build(foluser_params)
#foluser.id_watch = current_master.id_watch # <-- !!!
respond_to do |format|
if #foluser.save
# ...
end
end
end
end
Despite our extended conversation above, I'm still unclear what you're trying to achieve with the "password generation".
(Should it be generated in the front-end, or the back-end? Should it be stored encrypted, or in plain text? If encrypted, do you need to be able to reverse this encryption? Is it a "permanent" password, or a "temporary" password? ...)
Therefore, the following code should be taken with a big pinch of salt - since I still don't really know what the desired/correct behaviour is.
In the FolusersController, you've defined the following method:
def foluser_params
params.require(:foluser).permit(:name, :email, :numberphone, :password)
end
However, if you want the password to be generated by the server then you shouldn't be allowing the admin to set the password through the controller. Therefore, remove this parameter:
def foluser_params
params.require(:foluser).permit(:name, :email, :numberphone)
end
And then somewhere - perhaps in the controller, or as a hook in the model - set this password to something random:
class FolusersController < ApplicationController
def create
#foluser = current_master.folusers.build(foluser_params)
#foluser.password = SecureRandom.hex(10 + rand(6))
# ...
end
end
# or
class Foluser < ApplicationRecord
after_initialize :default_password
def default_password
self.password ||= SecureRandom.hex(10 + rand(6))
end
end
I think you found the solution, use rails callbacks in your model to extract this kind of logic from the controller.
But I'd rather use after_initialize than before_save so that you won't set a default password before each save(so possibly even update action)
Then use things like SecureRandom (ActiveSupport concern) (already bundled by rails, no requires required)
after_initialize :defaultpassword
...
def default_password
self.password ||= SecureRandom.hex(10 + rand(6))
end
not the best way to do random I know but feel free to customize it.
secure_random output examples:
=>bf8d42b174d297f6460eef
=>efd28869171a1ec89c3438
=>3855c61fb6b90ed549d777
I'm following tutorial: https://www.youtube.com/watch?v=7-1HCWbu7iU
I already did Pintrest clone using devise gem and had no issue. When I try to add current_user to links controller I get "undefined method current_user". I tried everything... even redoing the app from scratch, defining current_user, resetting the database. I guess the gem should handle the method automatically, right?
Here are my steps:
1. Generate new app - rails new raddit
2. Generate scaffold: rails g scaffold link title:string url:string
3. rake db:migrate
4. add gem 'devise', '~> 3.3.0' to gem file and run bundle install
5. run rails g devise:install
6. add file to development.rb - config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
7. add alerts to layout/application.html (as per devise documentation)
8. generate view file - rails g devise:views
9. generate user - rails g devise User
10. rake db:migrate
11. rails s
12. go to localhost:3000/users/sign_up (works ok)
13. Add relation to models: user.rb - has_many :links ; link.rb - belongs_to :user
14. Create migration: rails generate migration add_user_id_to_links user_id:integer:index
15. rake db:migrate
16. go to rails console and save assocation between user and links.
17. Add current_user to links controller - Getting undefined 'curren_user method' once I go to localhost:3000/links/new
Here is my code:
class LinksController < ApplicationController
before_action :set_link, only: [:show, :edit, :update, :destroy]
def index
#links = Link.all
end
def show
end
def new
#link = Link.current_user.links.build
end
def edit
end
def create
#link = current_user.build(link_params)
respond_to do |format|
if #link.save
format.html { redirect_to #link, notice: 'Link was successfully created.' }
format.json { render :show, status: :created, location: #link }
else
format.html { render :new }
format.json { render json: #link.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #link.update(link_params)
format.html { redirect_to #link, notice: 'Link was successfully updated.' }
format.json { render :show, status: :ok, location: #link }
else
format.html { render :edit }
format.json { render json: #link.errors, status: :unprocessable_entity }
end
end
end
def destroy
#link.destroy
respond_to do |format|
format.html { redirect_to links_url, notice: 'Link was successfully destroyed.' }
format.json { head :no_content }
end
end
private
def set_link
#link = Link.find(params[:id])
end
def link_params
params.require(:link).permit(:title, :url)
end
end
My models: link.rb
class Link < ActiveRecord::Base
belongs_to :user
end
My models: user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :links
end
You are getting the undefined method 'current_user' in the new action where you are calling Link.current_user.
def new
#link = Link.current_user.links.build
end
should be
def new
#link = current_user.links.build
end
Link does not have a current_user method, that is the problem. current_user is defined in the context of the controller and should be used as you do in the create action.
it should be
#link = current_user.links.build
in new action
if you have more problem than just type exit in new action and check the current_user in console.. You can get errors from console.. so every time check your console first.
use better_errors gem.. for more info about the particular error
Im trying to use the alternative of "foreign keys", embedded_in and embeds_many in rails 4. I'm sure there is a way round this and its making sense to me so far
My Models:
class Line
include Mongoid::Document
include Mongoid::Timestamps
embeds_many :stations
field :line, type: String
index({ starred: 1 })
end
class Station
include Mongoid::Document
include Mongoid::Timestamps
has_many :routes
embedded_in :line, inverse_of: :stations
field :name, type: String
end
Now I'm able to create a nested route such as:
http://localhost:3000/lines/:line_id/stations
with:
Rails.application.routes.draw do
resources :lines do
resources :stations
end
resources :routes
root 'lines#index'
end
My Stations Controller:
class StationsController < ApplicationController
before_action :load_line
before_action :set_station, only: [:show, :edit, :update, :destroy]
# GET /stations
# GET /stations.json
def index
#stations = #line.stations
end
# GET /stations/1
# GET /stations/1.json
def show
end
# GET /stations/new
def new
#station = #line.stations.build
end
# GET /stations/1/edit
def edit
end
# POST /stations
# POST /stations.json
def create
#station = #line.stations.build(station_params)
respond_to do |format|
if #station.save
format.html { redirect_to #station, notice: 'Station was successfully created.' }
format.json { render :show, status: :created, location: #station }
else
format.html { render :new }
format.json { render json: #station.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /stations/1
# PATCH/PUT /stations/1.json
def update
respond_to do |format|
if #station.update_attributes(station_params)
format.html { redirect_to #station, notice: 'Station was successfully updated.' }
format.json { render :show, status: :ok, location: #station }
else
format.html { render :edit }
format.json { render json: #station.errors, status: :unprocessable_entity }
end
end
end
# DELETE /stations/1
# DELETE /stations/1.json
def destroy
#station.destroy
respond_to do |format|
format.html { redirect_to stations_url, notice: 'Station was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_station
#station = #line.stations.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def station_params
params.require(:station).permit(:name)
end
def load_line
#line = Line.find(params[:line_id])
end
end
but when I visit the route I get:
message: Document(s) not found for class Line with id(s) :line_id. summary: When calling Line.find with an id or array of ids, each parameter must match a document in the database or this error will be raised. The search was for the id(s): :line_id ... (1 total) and the following ids were not found: :line_id. resolution: Search for an id that is in the database or set the Mongoid.raise_not_found_error configuration option to false, which will cause a nil to be returned instead of raising this error when searching for a single id, or only the matched documents when searching for multiples.
In your browser don't type http://localhost:3000/lines/:line_id/stations but http://localhost:3000/lines/1/stations !
If your routes.rb doesn't have the following you shoudl add it.
resources :lines do
resources :stations
end
PS: Please indent with two specs, they are common practice amongst ruby programmers.
I have an issue with associating two models in my rails application: Users & Profiles. An individual user profile should be created after a new user signs up. After signing up the user, saving data into the actual profile model is not successful. I can not get it to work. Please find a detailed description below.
Here is my setup:
I use Rails 4.0.0.rc2 and ruby 2.0.0p195.
Both models are associated like this:
profile.rb
class Profile < ActiveRecord::Base
belongs_to :user
end
user.rb
has_one :profile, dependent: :destroy
accepts_nested_attributes_for :profile
before_create :build_profile
As I use the devise gemI have created a registrationscontrollerto change the after_sign_up_path:
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
new_user_profile_path(:user_id => #user)
end
end
Whenever I sign up a new user the actual sign up works fine, the user is subsequently being directed to http://localhost:3000/users/42/profile/new for example. However, when I then enter the data into the profile form fields and click on submit I get the following error:
No route matches [POST] "/users/profile"
Although one could expect a routing error, you will notice a different error when looking at the actual domain:
http://localhost:3000/users//profile
In case you still want to have a look at my routes.rb please do (relevant excerpt):
devise_for :users, :controllers => { :registrations => "registrations" }
devise_scope :user do
get 'signup', :to => "devise/registrations#new", as: :signup
get 'login', :to => "devise/sessions#new", as: :login
get 'logout', :to => "devise/sessions#destroy", as: :logout
end
resources :users do
resource :profile
end
However, as noted above I don't really have a routing issue. It rather seems like I have an issue with the current user_id not being properly shown in the domain, which can be related to either my actual profile form or the new action on the profiles controller.
I start my profile form on new.html.erb like this:
<%= form_for #profile, url: user_profile_path(#user) do |f| %>
My profiles_controller.rblooks like this:
class ProfilesController < ApplicationController
before_action :set_profile, only: [:show, :edit, :update, :destroy]
# GET /profiles
# GET /profiles.json
def index
#profiles = Profile.all
end
# GET /profiles/1
# GET /profiles/1.json
def show
end
# GET /profiles/new
def new
#profile = Profile.new
end
# GET /profiles/1/edit
def edit
end
# POST /profiles
# POST /profiles.json
def create
#profile = Profile.new(profile_params)
respond_to do |format|
if #profile.save
format.html { redirect_to #profile, notice: 'Profile was successfully created.' }
format.json { render action: 'show', status: :created, location: #profile }
else
format.html { render action: 'new' }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /profiles/1
# PATCH/PUT /profiles/1.json
def update
respond_to do |format|
if #profile.update(profile_params)
format.html { redirect_to #profile, notice: 'Profile was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: #profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
#profile.destroy
respond_to do |format|
format.html { redirect_to profiles_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_profile
##profile = Profile.find(params[:id])
#profile = current_user.profile
end
# Never trust parameters from the scary internet, only allow the white list through.
def profile_params
params.require(:profile).permit(:photo, :address, :zip, :city, :state, :country, :telephone, :experience, :levels, :ages, :travel, :teachinglocation, :onlineteaching, :quotation, :aboutme, :subjects, :specialties, :lessondetails, :equipment)
end
end
What do I do wrong? How can I properly ensure that a newly signed up user can properly save his profile data?
It would be so great, if you could help me out.
It appears the Profile controller is not configured with the correct url - as can be seen by the missing User ID information.
You can see all currently defined paths by running the command rake routes from the command line.
I am a beginner at RESTful design and Rails, so do not consider the following expert advice.
Try changing the location of your redirect_to in the Profile create method:
# POST /profiles
# POST /profiles.json
def create
...
format.html { redirect_to user_profile_path(#profile.user, #profile), notice: 'Profile was successfully created.' }
...
If this works, the path should also be updated in the update and delete methods. As well as the format.json sections.
For additional info about this topic see:
2.9 Creating Paths and URLs From Objects
http://guides.rubyonrails.org/routing.html