auto-increment text_field number rails 3.2.6 - ruby-on-rails

i'v been researching trying to find the answer for this, but am struggeling to work it out. i have a booking_no text_field which i want to be automatically set when a user make a new booking through booking/new. i would like it to be an autonumber which just counts up by 1 evertime starting with 100.
I know it is probably easiest to do this in the model but i'm not sure how.
my booking.rb:
(i havent set the validates yet)
class Booking < ActiveRecord::Base
attr_accessible :booking_no, :car_id, :date, :user_id
belongs_to :car
belongs_to :user
end
EDIT for comment:
#error ArgumentsError in booking_controller#create
wrong number of arguments (1 for 0)
my booking_controller#create
def create
#booking = Booking.new(params[:booking])
respond_to do |format|
if #booking.save
format.html { redirect_to #booking, :notice => 'Booking was successfully created.' }
format.json { render :json => #booking, :status => :created, :location => #booking }
else
format.html { render :action => "new" }
format.json { render :json => #booking.errors, :status => :unprocessable_entity }
end
end
end

It's probably best if you set the booking_no as auto-increment field in the Database table itself..
Otherwise to manage it in your model, you can proceed something like:
before_create :increment_booking_no
def increment_booking_no
self.booking_no = (self.class.last.nil?) ? "0" : ((self.class.last.booking_no.to_i) + 1).to_s
end

Related

Can't dup FalseClass error with Dynamoid and Ruby on Rails over Heroku

Hi,
I'm using Ruby on Rails 5 and DynamoDB to persist my data and, in order to do this, i'm using Dynamoid ORM (https://github.com/Dynamoid/Dynamoid). When i instantiate the Video class in my local environment (with operations such as Video.new or Video.build) it works perfectly but when i deploy the application to Heroku the same operations fail with the error in the following image.
I've been googling the error but i haven't found anything to solve my problem. This is the only model/class with this problem, the others work fine.
Here are my Video model and Video controller.
Video Class
class Video
include Dynamoid::Document
table :name => :videos, :key => :id, :read_capacity => 5, :write_capacity => 5
field :nombre
field :apellido
field :email
field :titulo
field :descripcion
field :video_source
field :estado, :boolean, {default: false}
belongs_to :concurso
end
And my VideoController::create
def create
concurso = params[:video]
concurso_id = concurso[:id]
#concurso = Concurso.find(concurso_id)
#video = Video.new(:nombre => params[:nombre], :apellido => params[:apellido], :email => params[:email], :titulo => params[:titulo], :descripcion => params[:descripcion], :video_source => params[:video_source].original_filename)
#video.concurso = #concurso
respond_to do |format|
if #video.save
format.html { redirect_to #video, notice: 'Video was successfully created.' }
format.json { render :show, status: :created, location: #video }
else
format.html { render :new }
format.json { render json: #video.errors, status: :unprocessable_entity }
end
end
end
Does anyone know what could be the problem?
Thanks,

How to properly associate a model with multiple models?

I've tried to implement many of the proposed solutions in the relevant questions, but haven't yet found an answer ideal for what I'm trying to achieve in my Rails 4 application.
Basically my app has three models. Users, Hooks (embeddable pop-up widgets) and Contacts. Users can create Hooks and Contacts within their interface. And any visitor can create a new contact by filling out the Contact create form placed within a Hook's view, and that contact is associated with the user who created that hook.
That works fine, however when a contact is created by filling out a Hook's form, there's no connection to the specific Hook they completed the form in.
The next set of features I would like to add to my app requires not only associating each contact with a user, but also with the specific Hook it was created from.
I've read a bit into polymorphic associations (model belongs to multiple models) and I understand that's probably the way to go. After a couple of failed attempts, I'm not sure how to implement it though.
How would I associate Contacts with Hooks, so users can know which hook a contact was created from?
Here is what I currently have in the Hooks controller and model...
def create
#hook = hook.new(hook_params)
#hook.user = current_user
#contact = Contact.new(contact_params)
respond_to do |format|
if #hook.save
format.html { redirect_to #hook, notice: 'Hook was successfully created.' }
format.json { render :show, status: :created, location: #hook }
format.js
else
format.html { render :new }
format.json { render json: #hook.errors, status: :unprocessable_entity }
format.js
end
end
end
class Hook < ActiveRecord::Base
belongs_to :user
has_attached_file :image, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "https://s3.amazonaws.com/app/assets/leadmagnet.png"
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
end
And here is the contacts controller and model...
def create
#contact = Contact.new(contact_params)
#contact.user = current_user
respond_to do |format|
if #contact.save
if user_signed_in?
format.html { redirect_to #contact, notice: 'Contact was successfully created.' }
else
format.html { redirect_to #contact, notice: 'Contact was successfully created.' }
end
format.json { render :show, status: :created, location: #contact }
else
format.html { render :new }
format.json { render json: #contact.errors, status: :unprocessable_entity }
end
end
end
class Contact < ActiveRecord::Base
belongs_to :owner, :class_name => 'User'
belongs_to :user
validates :email, :presence => {:message => 'Email cannot be blank'}
end
First off, you should never ever ever create 2 unrelated models on the same controller action. It breaks conventions and will only lead to problems.
You do not need to directly associate Contacts to Users. You should associate Contacts to Hooks and then associate Contacts through Hooks
class User < ActiveRecord::Base
has_many :hooks
has_many :contacts, through: :hooks
end
class Hook < ActiveRecord::Base
belongs_to :user
has_many :contacts
accepts_nested_attributes_for :contacts
end
class Contact < ActiveRecord::Base
belongs_to :hook
end
Now on the create action of the ContactsController, you can first get the Hook either by URL param or passed via post body. You can first find the Hook and create the Contact on it via:
hook = Hook.find(hook_id)
#contact = hook.contacts.new(contacts_param)
If you want to create contacts when creating a new Hook, you need to add :contacts_attributes on the strong_params, then pass an array of contact attributes via the POST. Adding accepts_nested_attributes_for to the Hook model allows you to easily create Contacts while creating Hooks by simply entering:
#hook = Hook.new(hook_params)
If I understand correctly, you want to create both a Hook and a Contact, and associate both to current_user. In your code you create both, but you only associate #hook with the current_user, and only save it, while ignoring the #contact. Simply associate it and save it as well:
def create
#hook = hook.new(hook_params)
#hook.user = current_user
#contact = Contact.new(contact_params)
#contact.user = current_user
respond_to do |format|
if #hook.save && #contact.save
format.html { redirect_to #hook, notice: 'Hook was successfully created.' }
format.json { render :show, status: :created, location: #hook }
format.js
else
format.html { render :new }
format.json { render json: #hook.errors + #contact.errors, status: :unprocessable_entity }
format.js
end
end
end

Subform for parent object

So I've been holding off putting a question on here because I don't want to bother the community with stupid questions, but I'm going to ask for help now anyway.
I'm quite new to Ruby on Rails, and as you've probably read from the title, I'm having trouble with my subform. More specifically, with assigning the parent object to a client object. I'm building a system for my work in where employees can register repairs (mobile phones) and keep track of them. I'm building the client object with #repair = Repair.new, which works fine, but when I try to set the Client with #repair = Client.new, the :client_id on the repair stays null.
Here's my repair.rb: (some fields are in Dutch, please ignore that)
class Repair < ActiveRecord::Base
attr_accessible :imei, :klantnaam, :telefoon, :intake, :branch_id, :id, :client_id
attr_accessible :merk, :type, :batterij, :lader, :headset, :batterijklep, :carkit, :schade_toestel, :schade_scherm, :bon, :datum_bon, :klacht, :prijsindicatie
belongs_to :branch
belongs_to :client
accepts_nested_attributes_for :client
end
client.rb:
class Client < ActiveRecord::Base
attr_accessible :email, :firstname, :lastname, :number, :phone, :postalcode
has_many :repairs
end
repairs_controller.rb: (I've left the irrelevant methods out, I was getting tired of the 4 spaces :P)
class RepairsController < ApplicationController
# GET /repairs/new
# GET /repairs/new.json
def new
#repair = Repair.new
#repair.client = Client.new
if request.remote_ip == "xx.xx.xx.xx"
#repair.branch = Branch.where(:name => "Xxxxxxx").first
end
#repair.intake = Time.now
respond_to do |format|
format.html # new.html.erb
format.json { render json: #repair }
end
end
# POST /repairs
# POST /repairs.json
def create
#repair = Repair.new(params[:repair])
respond_to do |format|
if #repair.save
format.html { redirect_to #repair, notice: 'Repair was successfully created.' }
format.json { render json: #repair, status: :created, location: #repair }
else
format.html { render action: "new" }
format.json { render json: #repair.errors, status: :unprocessable_entity }
end
end
end
end
And this is the JSON I get from /repair/new.json:
{"batterij":null,"batterijklep":null,"bon":null,"branch_id":null,"carkit":null,"client_id":null,"created_at":null,"datum_bon":null,"headset":null,"id":null,"imei":null,"intake":"2013-02-01T23:29:10Z","klacht":null,"klantnaam":null,"lader":null,"merk":null,"pickup":null,"prijsindicatie":null,"schade_scherm":null,"schade_toestel":null,"telefoon":null,"updated_at":null}
By the way, the branch assignment works flawlessly... (It's null now because I'm not on the IP I specified in the new method)
Please help me out... :-(
Robin
Solved it!!
The code above all works flawlessly, the problem was a <% instead of <%= in my view, which made my subform not show up. Duhh.

Nice way of doing dual column validation

I'm using Rails 3 for this one. I've got a collections model, a user model and an intermediate subscription model. This way a user can subscribe to multiple collections, with a particular role. However, I don't want a user to be able to subscribe to the same collection twice.
So in my Subscription model I've got something like:
validate :subscription_duplicates
def subscription_duplicates
self.errors.add_to_base "This user is already subscribed" if Subscription.where(:user_id => self.user.id, :collection_id => self.collection.id)
end
However this seems ugly. Also, it breaks when I want to do something like the following in my collection controller:
def create
#collection = Collection.new(params[:collection])
#collection.subscriptions.build(:user => current_user, :role => Subscription::ROLES['owner'])
#collection.save
respond_with(#collection)
end
When I do the build the subscription does not have an id so I get a "Called id for nil" error.
Thanks for any guidance!
use validates_uniqueness_of
validates_uniqueness_of :user_id, :scope => :collection_id
First of all, your create action should always test if the object was saved, and if not then handle that (usually by re-rendering the new/edit page and showing the errors to the user).
A standard sort of create action would look like this (for a #post in this case):
def create
#post = Post.new(params[:post])
#created = #post.save
respond_to do |format|
if #created
flash[:notice] = 'Post was successfully created.'
format.html { redirect_to #post }
format.xml { render :xml => #post, :status => :created, :location => #post }
format.js
else
format.html { render :action => :new } #or edit or wherever you got here from
format.xml { render :xml => #post.errors, :status => :unprocessable_entity }
format.js
end
end
end
Shingara's approach to avoiding duplicates should work fine for you.

ActiveResource error handling

I have been searching for a while and yet I am not able to find a satisfactory answer as yet. I have two apps. FrontApp and BackApp. FrontApp has an active-resource which mimics a model in BackApp. All the model level validations live in BackApp and I need to handle those BackApp validations in FrontApp.
I have following active-resource code:
class RemoteUser < ActiveResource::Base
self.site = SITE
self.format = :json
self.element_name = "user"
end
This mimics a model which is as follows
class User < ActiveRecord::Base
attr_accessor :username, :password
validates_presence_of :username
validates_presence_of :password
end
Whenever I create a new RemoteUser in front app; I call .save on it. for example:
user = RemoteSession.new(:username => "user", :password => "")
user.save
However, since the password is blank, I need to pass back the errors to FrontApp from BackApp. This is not happening. I just don't understand how to do that successfully. This must be a common integration scenario; but there doesn't seem to be a good documentation for it?
My restful controller that acts as a proxy is as follows:
class UsersController < ActionController::Base
def create
respond_to do |format|
format.json do
user = User.new(:username => params[:username], :password => params[:password])
if user.save
render :json => user
else
render :json => user.errors, :status => :unprocessable_entity
end
end
end
end
end
What is it that I am missing? Any help will be much appreciated.
Cheers
From rails source code I figured out that the reason ActiveResource didn't get errors was because I wasn't assigning errors to "errors" tag in json. It's undocumented but required. :)
So my code should have been:
render :json => {:errors => user.errors}, :status => :unprocessable_entity
In the code:
class UsersController < ActionController::Base
def create
respond_to do |format|
format.json do
user = User.new(:username => params[:username], :password => params[:password])
if user.save
render :json => user
else
render :json => user.errors, :status => :unprocessable_entity
end
end
end
end
end
try to replace
user = User.new(:username => params[:username], :password => params[:password])
with
user = User.new(params[:user])
Your active-resource model pass the params like the hash above:
:user => { :username => "xpto", :password => "yst" }
This solution worked for me: https://stackoverflow.com/a/10051362/311744
update action:
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
Calling controller:
#remote_user = RemoteUser.find(params[:id])
if (#remote_user.update_attributes(params[:remote_user]))
redirect_to([:admin, #remote_user], notice: 'Remote user was successfully updated.')
else
flash[:error] = #remote_user.errors.full_messages
render action: 'edit'
end

Resources