Scaffolding Activerecord: Two Columns of the Same Data Type

Scaffolding ActiveRecord: two columns of the same data type

Just to tidy things up a bit, in your migration you can now also do:

create_table :videogames do |t|
t.belongs_to :developer
t.belongs_to :publisher
end

And since you're calling the keys developer_id and publisher_id, the model should probably be:

belongs_to :developer, :class_name => "Company"
belongs_to :publisher, :class_name => "Company"

It's not a major problem, but I find that as the number of associations with extra arguments get added, the less clear things become, so it's best to stick to the defaults whenever possible.

How can I have two columns in one table point to the same column in another with ActiveRecord?

class Ticket < ActiveRecord::Base
belongs_to :submitter, :class_name => "User"
belongs_to :assignee, :class_name => "User"
end

Should work.

Edit: Without trying it out, I'm not sure whether you need the :foreign_key parameter or not. My instinct is not, but it couldn't hurt.

Edit again: Sorry, left off the User -> Ticket associations. You didn't mention using them, and I typically will only add associations in one direction if I don't plan on using them in the other direction.

Anyway, try:

class User < ActiveRecord::Base
has_many :assigned_tickets, :class_name => "Ticket", :foreign_key => "assignee_id"
has_many :submitted_tickets, :class_name => "Ticket", :foreign_key => "submitter_id"
end

Can I have two different input fields and one column in the database?

Your model and database tables are the internals of your application and are not actually tied to the view by anything except how easy ActiveRecord makes it to use convention over configuration to link the two*.

In Rails style MVC the controller is responsible for passing user input to the model. Usually you would just do this with simple mass assignment:

class UsersController < ApplicationController
def create
@user = User.new(user_params)
# ...
end

private

def user_params
params.require(:user)
.permit(:email, :salary)
end
end

This is basically just passing a whitelisted hash of parameters straight to the model as is and it all gets passed to the setters that ActiveRecord magically created for you by reading the database schema.

But there is nothing stopping you from assigning attributes manually:

class UsersController < ApplicationController
def create
@user = User.new(user_params) do |user|
user.salary = calculated_salary
end
# ...
end

private

def user_params
params.require(:user)
.permit(:email)
end

def calculated_salary
if params[:user][:hourly_payment].present?
params[:user][:hourly_payment]
elsif params[:user][:monthly_payment].present?
params[:user][:monthly_payment].to_i / 168
else
0 # sorry no cookies for you
end
end
end

Or monkeying with the parameters object:

def user_params
params.require(:user)
.permit(:email)
.merge(salary: calculated_salary)
end

It is after all just a hash on steroids. The only thing that Rails will prevent you from is passing a parameters object that has not been whitelisted.

There is no stone tablet for what you can do in a controller. The only thing to bear in mind is that controllers are notoriously hard to test and fat controllers are a recipe for disaster.

If you're doing anything more complicated there are better solutions such as form objects, decorators or service objects.

Ruby on rails - Reference the same model twice?

Add this to your Model

belongs_to :sender, :class_name => "User"
belongs_to :recipient, :class_name => "User"

And you are able to call @message.sender and @message.recipient and both reference to the User model.

Instead of user:references in your generate command, you'd need sender:references and recipient:references

Two columns must not equal each other in Rails

Try it like this:

class Friendship < ActiveRecord::Base
validate :cannot_add_self

private

def cannot_add_self
errors.add(:user2_id, 'You cannot add yourself as a friend.') if user1_id == user2_id
end
end

Scaffolding A model with an attribute of type datetime creates a 10 years range in the form

This seems to be ok. Except did you put it inside the <%= %> ?

Edit: Also i noticed that you say your scaffold has published column whereas your date_select refers to the entered column.

As in, <%= f.date_select :published, :start_year => 1970, :end_year => 2020 %>
If that doesn't work you can also try,

<%= f.date_select :published, :start_year => Time.now.year - 40, :end_year => Time.now.year + 10 %>

I tried it and it works for me. Cheers! :)

Create relationships when scaffolding

Scaffold actually provides a way to generate relationships, you should use the :references data type

rails g scaffold Comment body:string author:string post:references

This will generate a migration for the comments table with a post_id field and index for it. The generator will also add belongs_to :post to the Comment model.

It will not however generate the reverse side of the relationship so you'll need to add

has_many :comments

to the Post model yourself. You will also need to add nested resource routing if this is something you need as the generator can not handle this.

How can two specs share the same it block?

Helper methods. (Excuse the horribleness of the example. Would have been better if you'd posted yours :P)

describe "soup" do
def soup_is_salty # helper method! \o/
soup.add(:meat)
soup.add(:egg)
soup.cook
soup.salty?
end

describe "with carrot" do
before(:all) do
soup.add(:carrot)
end

it "should be salty" do
soup_is_salty # get help from helper method! \o/
end
end

describe "soup with potato" do
before(:all) do
soup.add(:potato)
end

it "should be salty" do
soup_is_salty # get help from helper method! \o/
end
end
end


Related Topics



Leave a reply



Submit