I have two models: User and Sensor. I want to set dependence has_many and belongs_to.
Sensor model
class Sensor < ActiveRecord::Base
attr_accessible :user_id, :data, :ids, :voltage, :status
belongs_to :user
end
and User model
class User < ActiveRecord::Base
has_many :sensors
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
In the new migration i created new column
class AddUserId < ActiveRecord::Migration
def change
add_column :sensors, :user_id, :integer
end
end
And Create method in the Sensor Controller
def create
#sensor = Sensor.new(sensor_params)
respond_to do |format|
if #sensor.save
format.html { redirect_to #sensor, notice: 'Sensor was successfully created.' }
format.json { render action: 'show', status: :created, location: #sensor }
else
format.html { render action: 'new' }
format.json { render json: #sensor.errors, status: :unprocessable_entity }
end
end
end
And when i press the create button,the dependence doesn't set
I guess you have current_user in your application.
SO in the create action, please try the following code.
def create
#sensor = current_user.sensors.new(sensor_params)
# YOUR CODE GOES HERE
end
Related
I have a Shop model and a User model. Logic is that users can have one shop and shops can have one users associated with them, so I am using the has_one: shop association.
But while creating a new shop for a new user am getting this error
undefined method 'shops' for #<\User:0x007f6f30659068> Did you mean? shop shop=
I don't understand what's gone wrong. I am sure I must have done something stupid, here's my code:
class ShopsController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
def new
#shop = current_user.shop.build
end
def create
#shop = current_user.shops.build(shop_params)
#shop.user = current_user
respond_to do |format|
if #shop.save
format.html { redirect_to #shop, notice: 'Shop was successfully created.' }
format.json { render :show, status: :created, location: #shop }
else
format.html { render :new }
format.json { render json: #shop.errors, status: :unprocessable_entity }
end
end
end
private
def shop_params
params.require(:shop).permit(:name, :description, :imageshop, :location, :web, :email, :phone, :business_type, :category)
end
end
class Shop < ApplicationRecord
mount_uploader :imageshop, ImageUploader
belongs_to :user
end
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :products, dependent: :destroy
has_one :shop
end
I think you need to change
#shop = current_user.shops.build(post_params)
to
#shop = current_user.build_shop(post_params)
This is because you have specified that a User can have one Shop.
Hope it helps!
I have a User object and an Orgs object that are associated through a HABTM join table. I want to send an email to the users when the Orgs object is updated AND the Org.approved value is set to true. I have an approved boolean on the Org.
I think I've gotten most of the way there but I need help with the step of actually sending the email.
Here's my code
class OrgMailer < ApplicationMailer
default from: 'myemail#example.co'
def org_approved(user, org)
#user = user
#orgs = User.orgs.all
#url = 'http://example.com/login'
mail(to: #user.email, subject: 'Your listing has been approved.')
end
end
User.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
has_and_belongs_to_many :orgs, join_table: :orgs_users
end
Org.rb
class Org < ApplicationRecord
has_and_belongs_to_many :users, join_table: :orgs_users
# after_update :send_approved_listing_email, only: [:update]
attachment :company_image
def send_approved_listing_email
OrgMailer.org_approved(i).deliver_now if org.approved === true
end
end
UPDATED: ADDED ORG_CONTROLLER
I've edited my code to look like the answer below but am now getting a new error: uninitialized constant Org::OrgsUser
It's caused when I hit the #org.users << #user line in the create action.
If I delete this line, I'm able to create an org but it's not associating properly.
org_controller.rb
class OrgsController < ApplicationController
before_action :set_org, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
def index
#orgs = Org.all
#tags = ActsAsTaggableOn::Tag.all
end
def show
end
def new
#org = Org.new
end
def contest
end
def edit
end
def create
#user = current_user
#org = Org.new(org_params)
#org.users << #user
respond_to do |format|
if #org.save
format.html { redirect_to thankyou_path, notice: 'Your listing was successfully created. Our team will approve your listing after review.' }
format.json { render :show, status: :created, location: #org }
else
format.html { render :new }
format.json { render json: #org.errors, status: :unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #org.update(org_params)
format.html { redirect_to #org, notice: 'Listing was successfully updated.' }
format.json { render :show, status: :ok, location: #org }
else
format.html { render :edit }
format.json { render json: #org.errors, status: :unprocessable_entity }
end
end
end
def destroy
#org.destroy
respond_to do |format|
format.html { redirect_to orgs_url, notice: 'Listing was successfully destroyed.' }
format.json { head :no_content }
end
end
def tagged
if params[:tag].present?
#orgs = Org.tagged_with(params[:tag])
else
#orgs = Org.postall
end
end
private
def set_org
#org = Org.find(params[:id])
end
def org_params
params.require(:org).permit(:twitter, :linkedin, :facebook, :name, :offer, :offercode, :url, :descrption, :category, :approved, :company_image, :tag_list => [])
end
end
I'm using active admin for my admin panel and have a batch action to update any selected orgs and approve them. I think what I'm missing is that in the send_approved_listing_email method I need to iterate through the orgs and email each user when the org is approved.
Right now nothing happens on update so I'm sure I'm not doing this correctly. What am I missing? How should I write this?
I would create a model for the join table rather than using habtm. That way you can use a callback when the join object is saved:
class User < ApplicationRecord
has_many :orgs_users
has_many :orgs, through: :orgs_users
end
class Org < ApplicationRecord
has_many :orgs_users
has_many :users, through: :orgs_users
end
class OrgsUsers < ApplicationRecord
belongs_to :org
belongs_to :user
after_create :send_approved_listing_email
def send_approved_listing_email
OrgMailer.org_approved(user, org).deliver_now if org.approved === true
end
end
I have a User model generated using Devise. This User model has 2 types (Buyer or Seller) created using Polymorphic Associations.
class Buyer < ActiveRecord::Base
has_one :user, as: :owner, dependent: :destroy
accepts_nested_attributes_for :user
validates_presence_of :user
validates_associated :user
class User < ActiveRecord::Base
after_commit :transaction_success
after_rollback :transaction_failed
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
belongs_to :owner, polymorphic: true
validates :email, presence: true
validates :first_name, presence: true
private
def transaction_success
logger.info "Transfer succeed for Account #{self.to_param}"
end
def transaction_failed
logger.warn "Transfer failed for Account #{self.to_param}"
end
end
When an User is Registered, he does it from an specific registration link (/buyer/new or /seller/new), calling the create method from the controller:
def create
#buyer = Buyer.new(buyer_params)
#user = User.new(user_params)
respond_to do |format|
begin
User.transaction do
#buyer.save
#user.owner_id = #buyer.id
#user.owner_type = "Buyer"
#user.save
end
format.html { sign_in_and_redirect #user, notice: 'User was successfully created.' }
format.json { render :show, status: :created, location: #user }
rescue ActiveRecord::Rollback
format.html { render :new }
format.json { render json: #user.errors, status: :unprocessable_entity }
end
end
end
The problem is that sometimes the transaction fails but saves a Buyer without an User. Also, the Devise validations, or any validation that I include in the User Model doesn't make any difference, allowing users to be created without any email, password etc.
How can I fix the transaction and make sure that the validations work??
Here how I would like things to work. I am not sure it is possible this way…
The Seller registers and can create a Resa which attribute is request_email: [DONE]
Once the Resa is created, an e-mail is sent to the request_email [DONE] asking to click on the link to register as a Buyer.
In this Buyer registration form, the e-mail field should be pre-filled with the request_email from the Resa. Once the buyer is saved, the Resa object should see its attribute buyer_id be updated from nilto the id of the Buyer object created.
Devise was added to Seller and Buyer.
Questions: are the following models and associations correctly designed to allow the process described above?
If yes, how to pass the resa_id and the request_email in the link for creating the Buyer (pre-filled form) ?
Please feel free to suggest a smarter way to do things if you feel this is the wrong way.
models/seller.rb
class Seller < ActiveRecord::Base
has_many :resas
has_many :buyers, :through => :resas
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
end
models/resa.rb
class Resa < ActiveRecord::Base
belongs_to :seller
belongs_to :buyer
end
models/buyer.rb
class Buyer < ActiveRecord::Base
has_many :resas
has_many :sellers, :through => :resas
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable
end
controllers/resas_controller.rb
class ResasController < ApplicationController
before_action :set_resa, only: [:show, :edit, :update, :destroy]
before_action :authenticate_seller!
…
def create
#resa = current_seller.resas.new(resa_params)
#resa.request_status = "Pending"
##resa.seller_id = current_seller.id
respond_to do |format|
if #resa.save
ResaMailer.request_mail(#resa).deliver
format.html { redirect_to #resa, notice: 'Resa was successfully created.' }
format.json { render action: 'show', status: :created, location: #resa }
else
format.html { render action: 'new' }
format.json { render json: #resa.errors, status: :unprocessable_entity }
end
end
end
…
end
controllers/buyers_controller.rb
class BuyersController < ApplicationController
def create
#buyer = Buyer.new(buyer_params)
#resa = Resa.find(params[:resa_id])
respond_to do |format|
if #buyer.save
format.html { redirect_to #buyer, notice: 'Buyer was successfully created.' }
format.json { render action: 'show', status: :created, location: #buyer }
else
format.html { render action: 'new' }
format.json { render json: #buyer.errors, status: :unprocessable_entity }
end
end
end
end
Please let me know if you need further informations.
I assume your ResaMailer.request_mail is generating the link for the buyer registration. So in this link you can add a token
http://your.site/buyer/new?token=abcdef
The idea is to generate a token, store it in a table (perhaps your resas table) and along in the same record you can store the other fields you will need to retrieve during the buyer registration (like request_email for example)
Then in your BuyersController new action you can fetch the data using that token, and pre-fill the form.
class BuyersController
def new
#resa = Resa.find_by(token: params[:token])
# Use #resa to prefil the form in `new` action
end
end
As for the buyer_id you can't get a valid id before the record is created, but if your concern is to link the resa record with the newly created buyer, you can use the token I mentioned earlier to retrieve the resa record's id at the time of the buyer registration, then update this record with the newly created buyer id.
Hope it's clear, let me know.
I have a page that has a list of referrals on it. I have a button on each of the referrals that is set to reply to the referral. I don't need any pop up or form to show except for a flash message to show the user has successfully replied to the referral and toggling a class on the button when a user replies. Upon replying to the referral, email(is index for the table) is passed, referralid is also passed to the reply table. I have tried many methods, but I'm getting nowhere with the controllers. I created proper associations on the models, but still getting nowhere in the controller logic to create a reply record for every reply. Here are my models:
Referral Model
class Referral < ActiveRecord::Base
attr_accessible :referraltype
belongs_to :user
validates :user_id, presence: true
has_many :replies
def nil_zero?
self.nil? || self == 0
end
end
User Model
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
attr_accessible :name, :email, :password, :password_confirmation, :remember_me, :provider, :uid, :image
has_attached_file :image, styles: { medium: "320x320>", thumb: "50x50" }
has_many :referrals
has_many :replies
end
Replies Controller
class RepliesController < ApplicationController
end
Reply Model
class Reply < ActiveRecord::Base
belongs_to :user
belongs_to :referral
end
Referrals Controller
class ReferralsController < ApplicationController
before_filter :authenticate_user!
def reply_to_referral
#referral = Referral.find(params[:referral_id])
#replier_id = params[:replier_id]
#reply = #referral.replies.create(replier_id: #replier_id)
flash[:success] = "Referral reply sent."
redirect_to root_path
end
# GET /referrals
# GET /referrals.json
def index
#referrals = Referral.order("created_at desc")
#referrals
respond_to do |format|
format.html # index.html.erb
format.json { render json: #referrals }
end
end
# GET /referrals/1
# GET /referrals/1.json
def show
#referral = Referral.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #referral }
end
end
# GET /referrals/new
# GET /referrals/new.json
def new
#referral = current_user.referrals.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #referral }
end
end
# GET /referrals/1/edit
def edit
#referral = current_user.referrals.find(params[:id])
end
# POST /referrals
# POST /referrals.json
def create
#referral = current_user.referrals.new(params[:referral])
respond_to do |format|
if #referral.save
format.html { redirect_to #referral, notice: 'Referral was successfully created.' }
format.json { render json: #referral, status: :created, location: #referral }
else
format.html { render action: "new" }
format.json { render json: #referral.errors, status: :unprocessable_entity }
end
end
end
# PUT /referrals/1
# PUT /referrals/1.json
def update
#referral = current_user.referrals.find(params[:id])
respond_to do |format|
if #referral.update_attributes(params[:referral])
format.html { redirect_to #referral, notice: 'Referral was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #referral.errors, status: :unprocessable_entity }
end
end
end
# DELETE /referrals/1
# DELETE /referrals/1.json
def destroy
#referral = current_user.referrals.find(params[:id])
#referral.destroy
respond_to do |format|
format.html { redirect_to referrals_url }
format.json { head :no_content }
end
end
end
Routes.rb
GemPort::Application.routes.draw do
resources :referrals do
resources :replies
member do
put "reply_to_referral"
end
end
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
root :to => 'pages#home'
get 'about' => 'pages#about'
end
Migration for the Replies table
class CreateReplies < ActiveRecord::Migration
def change
create_table :replies do |t|
t.references :user
t.references :referral
t.timestamps
end
add_index :replies, :user_id
add_index :replies, :referral_id
end
end
code on the _referral.html.haml partial that is giving the error:
= link_to '<i class="icon-ok icon-large pull-right icon-grey" rel="tooltip" title="Reply"> Reply</i>'.html_safe, reply_to_referral_path(referral_id: referral.id, replier_id: current_user.id)
I know this must be simple to do in the controller, I tried using a helper but got nowhere
Add your routes and controller and we can give you a better answer, but I'm guessing that this isn't working since you're passing an email to the route.
Emails have full stops (.) which can break your route unless you add constraints to the route.
Try changing your route to something like:
resources :referrals do
member do
put "reply_to_referral" # will give you referrals/:id/reply_to_referral
end
end
Now change your link to reply_to_referral_path(id: referral.id, email: current_user.email), this should come out as /referrals/32/reply_to_referral?email=user#email.com
Then in referrals controller:
def reply_to_referral
#referral = Referral.find(params[:id])
#email = params[:email]
# now make sure your referral_replies table has a column called 'email' and
# also one called 'referral_id', then you can do:
#referral_reply = #referral.referral_replies.create(email: #email)
flash[:success] = "Referral reply sent."
redirect_to # wherever required
end
You could do something similar by adding a constraint to the route, or by passing in the user's id instead of email and then querying the database.
To style the button you can then check if the referral has any replies:
<% if referral.referral_replies.any? %>
# add a CSS class
<% end %>