I have a rails application with
1)User Model
class User < ActiveRecord::Base
has_secure_password
has_many :projects
end
2) Project Model
class Project < ActiveRecord::Base
belongs_to :user
end
3) CreateUser in db/migrate
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :first_name
t.string :last_name
t.string :email
t.string :password_digest
t.references :projects
t.timestamps null: false
end
end
end
4) CreateProject in db/migrarte
class CreateProjects < ActiveRecord::Migration
def change
create_table :projects do |t|
t.string :name
t.string :description
t.references :users
t.timestamps null: false
end
end
end
Now in my Controller, I have a function
def create
#project = Project.new(project_params)
#user = User.find(session[:user_id])
if #project.save
#user.projects << Project.find(#project.id)
redirect_to '/'
else
redirect_to '/project/create'
end
end
But when i call http://localhost:3000/project/new, I receive following error :-
-NoMethodError in ProjectController#create
-undefined method `projects' for # User
with
#user.projects << Project.find(#project.id)
highlighted in the extracted source.
Am I entering the record into has_many relationship correct, or is my syntax wrong?
I ran the following code in the console the server,
user = User.find(1)
user.projects
I received this error message:
NoMethodError: undefined method `projects' for #<User:0x00000001f5b508>
from /home/harshil/.rvm/gems/ruby-2.2.1/gems/activemodel-4.2.4/lib/active_model/attribute_methods.rb:433:in `method_missing'
from /home/harshil/.rvm/gems/ruby-2.2.1/gems/activemodel-4.2.4/lib/active_model/attribute_methods.rb:433:in `method_missing'
Thanks
It seems the CreateUser migration is incorrect. It should not reference the projects. Projects should reference the User, which you have done correctly.
I believe this is confusing ActiveRecord
try removing t.references :projects from the UserCreate migration and try again
Related
Hi i'm having a problem with a rails association. I have the Table Users and the table Roles. Here are my migrations:
class CreateUsers < ActiveRecord::Migration[5.2]
def change
create_table :users do |t|
t.string :email
t.string :password_digest
t.belongs_to :role, index: true, foreign_key: true
t.timestamps
end
end
end
class CreateRoles < ActiveRecord::Migration[5.2]
def change
create_table :roles do |t|
t.string :name
t.string :code
t.timestamps
end
end
end
Im having the problem when I create a user with a role that I had previously created
Role.create(name: 'Super Admin', code: 'super_admin')
User.create(email: 'a#b.com', password: 'abcdefg', role_id: 1)
When I try to do User.first.role I get that the method role is undefined. As far as i know When i do that i should get an active record with the role.
What i am doing wrong. Please Help
You need to add the relation to your model. In user.rb:
class User < ApplicationRecord
belongs_to :role
# other code
end
It will generate the ActiveRecord methods you are looking for.
When I access localhost:3000,
my browser told error of NoMethodError in ConnectionController#index.
Also,I was told that undefined method `action' for ConnectionController(Table doesn't exist):Class.
The error browser told connection_controller.rb of 26 line was wrong but I didn't write codes so long like 26 lines.
send(name, *arguments, &block)
else
super
end
end
I wrote ,in connection_controller.rb
class ConnectionController < ActiveRecord::Base
def index
personal = {'name'=>'Yamada','old'=>28}
render :json => personal
end
end
in routes.rb,
Rails.application.routes.draw do
namespace :connection do
get '/',action:'index'
end
end
in schema.rb
ActiveRecord::Schema.define(version: 20170101073143) do
create_table "userdata", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
in migrate file ,
class CreateUserdata < ActiveRecord::Migration
def change
create_table :userdata do |t|
t.string :name
t.text :image
t.timestamps null: false
end
end
end
in model,
class Userdatum < ActiveRecord::Base
user = User.new
user.name = "XXX"
user.email = "mail"
user.save
end
Please note that a controller in Rails should extend ActionController class and a Model should extend ActiveRecord::Base class.
You seems to have done this
class ConnectionController < ActiveRecord::Base
end
inside your controller.
It should be
class ConnectionController < ApplicationController
end
I want to add like, favorite and inappropriate button to microposts.
User can like a micropost only one time. But also user who likes the micropost can click the favorite button.
When I tried that in rails console I've an error.
Error
irb(main):002:0> micropost=Micropost.first
ArgumentError: wrong number of arguments (3 for 0)
from /Users/tanerkoroglu/.bundler/ruby/2.0.0/make_flaggable-99297edddfec/lib/make_flaggable.rb:22:in `make_flaggable'
from /Users/tanerkoroglu/Desktop/Wishpere2/app/models/micropost.rb:9:in `<class:Micropost>'
from /Users/tanerkoroglu/Desktop/Wishpere2/app/models/micropost.rb:1:in `<top (required)>'
from /Library/Ruby/Gems/2.0.0/gems/activesupport-4.2.4/lib/active_support/dependencies.rb:457:in `load'
micropost.rb
make_flaggable :like, :inappropriate, :favorite
user.rb
make_flagger :flag_once => true
create_make_flaggable_tables.rb
class CreateMakeFlaggableTables < ActiveRecord::Migration
def self.up
create_table :flaggings do |t|
t.string :flaggable_type
t.integer :flaggable_id
t.string :flagger_type
t.integer :flagger_id
t.text :reason
t.timestamps
end
add_index :flaggings, [:flaggable_type, :flaggable_id]
add_index :flaggings, [:flagger_type, :flagger_id, :flaggable_type, :flaggable_id], :name => "access_flaggings"
end
def self.down
remove_index :flaggings, :column => [:flaggable_type, :flaggable_id]
remove_index :flaggings, :name => "access_flaggings"
drop_table :flaggings
end
end
create_microposts.rb
class CreateMicroposts < ActiveRecord::Migration
def change
create_table :microposts do |t|
t.text :content
t.references :user, index: true, foreign_key: true
t.timestamps null: false
end
add_index :microposts, [:user_id, :created_at]
end
end
add_flaggings_count_to_microposts.rb
class AddFlaggingsCountToMicroposts < ActiveRecord::Migration
def change
add_column :microposts,:flaggings_count, :integer
end
end
add_flaggings_count_to_users.rb
class AddFlaggingsCountToUsers < ActiveRecord::Migration
def change
add_column :users, :flaggings_count, :integer
end
end
First of all make_flaggable method doesn't accept any parameter as mentioned in the source code here and that's why you see 3 for 0 argument error.
You don't have to pass any argument to make_flaggable in your model.
micropost.rb
make_flaggable
By default, the model becomes flaggable by any other model.
If you want it to be flaggable by models where it has been marked as flagger. Then you can restrict micropost be flagged only by those models which are marked as flagger.
micropost.rb
make_flaggable :once_per_flagger => true
So for your model, don't pass any parameter to make_flaggable.
I have a problem with copying database records. I have a simple model User, that contains one-to-many relation with Language model and many-to-many relation with Skill model. I wanted to use amoeba gem to copy records with all associations. One-to-many copying works fine, but many-to-many doesn't copy at all.
Here's the code of User and Skill model:
user.rb
class User < ActiveRecord::Base
belongs_to :language
has_and_belongs_to_many :skills
validates_presence_of :email, :name
validates :email,
presence: { with: true, message: "cannot be empty" },
uniqueness: { with: true, message: "already exists in database" }
amoeba do
enable
end
end
skill.rb
class Skill < ActiveRecord::Base
has_and_belongs_to_many :users
end
I have also migration files that crates users, skills and skills_users tables:
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name, null: false
t.string :email, null: false
t.references :language
t.timestamps null: false
end
end
end
.
class CreateSkills < ActiveRecord::Migration
def change
create_table :skills do |t|
t.string :name
t.timestamps null: false
end
end
end
.
class AddUsersSkillsTable < ActiveRecord::Migration
def change
create_table 'skills_users', :id => false do |t|
t.column :user_id, :integer
t.column :skill_id, :integer
end
end
end
Controller action 'show' in users_controller looks like this:
def copy
#user_copy = #user.dup
if #user_copy.save(validate: false)
redirect_to action: "index"
end
end
I tried copying relations in user.rb like this, but it didnt work:
amoeba do
enable
clone [:skills]
end
What may cause the problem?
Ok, I found the mistake. I wrote
#user_copy = #user.dup
in the controller file instead of
#user_copy = #user.amoeba_dup
I've the following migrations and models:
class CreatePlatforms < ActiveRecord::Migration
def change
create_table :platforms do |t|
t.integer :user_id
t.string :name
t.string :platform_id
t.timestamps
end
end
end
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :email
t.string :first_name
t.string :last_name
t.string :gender
t.date :birthday
t.timestamps
end
end
end
class Platform < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
attr_accessible :email, :first_name, :last_name, :gender, :birthday
has_many :platforms
end
With this definition I can create users and platforms:
user = User.new
platform1 = Platform.new
platform2 = Platform.new
And even I can associate users to platforms:
platform1.user = user
But when I try to associate platforms to users or get the platforms from a users it crashes:
user.platforms << user or user.platforms
NoMethodError: undefined method `platforms' for #<User:0x007f8cfd47a770>
As it turns out, the problem is the database field platform_id. This messes up rails. Simply delete it and it'll work.