Ruby on Rails model/controller access - ruby-on-rails

I have two models, subject and page. I created a one-to-many association between them.
class Subject < ActiveRecord::Base
has_many :pages
attr_accessible :name
attr_accessible :position
attr_accessible :visible
attr_accessible :created_at
end
and
class Page < ActiveRecord::Base
belongs_to :subject
attr_accessible :subject_id
attr_accessible :name
attr_accessible :permalink
attr_accessible :position
attr_accessible :visible
attr_accessible :created_at
end
As mentioned above, I have two models, and I want to access all subject names which are in the Subject model to the page model/controller...

Give this a try:
Subject.select("subjects.name").joins(:pages).uniq

If you want to get all the subjects saved in a subject model use:
Subject.pluck(:name)
or to access a subjects associated with particular page:
page = Page.first
page.subject #subject object associated with the page

Below is how you can access subject's pages or page's subject.
s = Subject.create(<params>)
s.pages # array of page objects
p = Page.create(<params>)
p.subject # subject object

Related

Rails schema scaffolding

I have one project for school and I am little bit confused how to make tag and category asociated posts so when I was looking for some tips in google I found this thread. So I tried scaffolding as described and it was working just fine, but when I ran the server and tried to create new post this appeared:
ActiveModel::MassAssignmentSecurity::Error in PostsController#create
Can't mass-assign protected attributes: category, user
So I really don't know what is wrong but I can use some help. Or maybe there can be suggested another way, mabe simpler how to scaffold posts with tags and categories.
Thank you very much
Here are the models:
class Post < ActiveRecord::Base
belongs_to :category
belongs_to :user
attr_accessible :body, :title, :category, :user
end
class Category < ActiveRecord::Base
attr_accessible :name
end
class Serie < ActiveRecord::Base
attr_accessible :name, :website
end
class Tag < ActiveRecord::Base
attr_accessible :name
end
class TagsSerie < ActiveRecord::Base
belongs_to :serie
belongs_to :tag
# attr_accessible :title, :body
end
class TagsPost < ActiveRecord::Base
belongs_to :post
belongs_to :tag
# attr_accessible :title, :body
end
class User < ActiveRecord::Base
attr_accessible :email, :password
end
Add attr_accessible in your post model:
class Post < ActiveRecord::Base
attr_accessible :category_id, :user_id, :other_attributes_from_post_model
end
Try setting attr_accessible :category_id, :user_id in your post model.
By default, Rails creates the scaffolded models with all its attributes non-accessible, so they are not available to edit by an external user.
So, when you tried to create a new Post, the error message raised, as category and user are protected attributes of Post.
You should review your app/models/post.rb and the rest of your models in the same folder to define as accessible those attributes that should be editable by an external user (a web user, for instance).
class Post < ActiveRecord::Base
attr_accessible :category_id, :user_id
end
On the other hand, the so accessible attributes are not protected any more for external edition so you should not use attr_accessible for all of them but just for ones that you will really allow to be modified externally.

Rails - correct way to refer model instance to second model instance by console

My Rails application contains two models named customer and order
class Customer < ActiveRecord::Base
attr_accessible :name
end
class Order < ActiveRecord::Base
belongs_to :customer
# attr_accessible :title, :body
end
In the console I created instance to the customer model:
c=Customer.new(:name=>"Noa")
Now I want to create instance to order model which refer to "c"
How can I do it?
Thanks!
The easiest way is to have a has_many inside the Customer class:
class Customer < ActiveRecord::Base
attr_accessible :name
has_many :orders
end
and then you can do the following to associate a new order to your customer.
order = c.orders.build :attribute => 'value', # ...
You could find here more details about how to build associations between object in Rails.

accessing data in many to many relations

I created many to many association of Teacher and Sclass. ClassTeacher is the join table name.
class Teacher < ActiveRecord::Base
has_many :class_teachers
has_many :Sclasses, :through => :class_teachers
attr_accessible :teacher_id
attr_accessible :tname
attr_accessible :mob
attr_accessible :email
end
class Sclass < ActiveRecord::Base
set_primary_key :year
has_many :class_teachers
has_many :teachers, :through => :class_teachers
attr_accessible :year
end
class ClassTeacher < ActiveRecord::Base
belongs_to :teacher
belongs_to :sclass
attr_accessible :year
attr_accessible :teacher_id
end
I have tlist.html.erb, tnew.html.erb in view -> teachers folder, similarly I have slist.html.erb, snew.html.erb in view -> sclasses folder.
When I add a record for Teacher, it should ask for years too and save the record. Similarly for year it should ask for teacher_ids and save the record. How can I do this?Where will these records be saved?
I'm not sure this answers your question but when you set up a many-to-many relationship your model gets some 'virtual' attributes, called [association_name]_ids. So in your case the Sclass model will have a teacher_ids attribute, and the Teacher model will have sclass_ids.
So if for example you wanted to assign teachers with ids 1, 2 and 3 to the first sclass you could do this:
sclass = Sclass.first
sclass.teacher_ids = [1, 2, 3]
sclass.save
To do this in a form you'd probably want something like a row of checkboxes with the name sclass[teacher_ids][] (when creating/editing an Sclass), something like this:
<% for teacher in Teacher.all -%>
<%= checkbox_tag "sclass[teacher_ids][]", teacher.id %>
<% end -%>

accessing the data from another model in ruby on rails

I have 2 models named Subject & Page. there is one to many association between them.
class Subject < ActiveRecord::Base
has_many :pages
attr_accessible :name
attr_accessible :position
attr_accessible :visible
attr_accessible :created_at
end
and
class Page < ActiveRecord::Base
belongs_to :subject
attr_accessible :subject_id
attr_accessible :name
attr_accessible :permalink
attr_accessible :position
attr_accessible :visible
attr_accessible :created_at
end
I have list.html.erb in view -> pages folder.
Q. My qus is I want to show all the subject_id in list.html.erb. how?
for that which changes I have to do in pages_controller & list.html.erb so that I will got solution...
You can access any Model in any Controller in following way
#instance_variable = ModelClass.all
In your case it should be something like following
pages_controller.rb
def list
#subjects_list = Subject.all
end
app/views/pages/list.html.erb
<% for subject in #subjects_list %>
<!-- Your Code Here -->
<% end %>

Validating a self-referential association doesn't link back to the original instance in rails

I have a many-to-many model, following the example in this great railscast
My model links authors to each other. I'd like to validate that an author cannot friend himself. I know I can handle this at the UI level, but I'd love to have a validation in place to prevent a bug in the UI from allowing it. I've tried validates_exclusion_of, but it doesn't work. Here's my model for the relationship:
class Friendship < ActiveRecord::Base
# prevent duplicates
validates_uniqueness_of :friend_id, :scope => :author_id
# prevent someone from following themselves (doesn't work)
validates_exclusion_of :friend_id, :in => [:author_id]
attr_accessible :author_id, :friend_id
belongs_to :author
belongs_to :friend, :class_name => "Author"
end
You'll have to use a custom validation:
class Friendship < ActiveRecord::Base
# ...
validate :disallow_self_referential_friendship
def disallow_self_referential_friendship
if friend_id == author_id
errors.add(:friend_id, 'cannot refer back to the author')
end
end
end

Resources