Conditional 'attr_accessible' using ActiveResource in Ruby on Rails - ruby-on-rails

I have two RoR3 application:
http://users.domain.local
http://profiles.domain.local
I created the 'users/models/profile.rb':
class Profile < ActiveResource::Base
self.site = "http://profiles.domain.local"
end
In 'profiles/models/profile.rb' I have:
attr_accessible :name
My profile's SQL table contains these columns:
id
name
user_id
So if I run Profile.create(:name => "test_name") a new profile will be created in http://profiles.domain.local with the name "test_name".
For obvious security reasons, I don't want to make accessible the 'user_id' attribute, but I need to set that on the profile creation from the 'users' application.
I tryed a lot of way do make that, but I can't find an easy solution. Maybe, it is possible with an if statement near the 'attr_accessible' of the 'profile' application that fill a request from the 'user' application.
Can somebody help me?

You could try something like what Amazon Web Services does: use a very long, randomly generated key with each request. Check that key is correct in your profiles app, and if yes, update the attribute.

Solution: Don't use simply Profile.create, use the association builders instead. Protect the user_id attribute and use user.profiles.create!(params[:profile]) to have it automatically set the user_id field for profiles to whatever the user object is.

Related

How do I associate two entries in a database that are connected through a many-to-many relationship in Rails?

How do I associate two entries in a database that are connected through a many-to-many relationship in Rails?
I'm trying to associate Users and Issues for an issue tracker. I'm using has_and_belongs_to_many, not :through. I have a :user_id and :issue_id available to me, but there doesn't seem to be User.issues.find(id) or Issue.users.find(id) available to me. I have a route post "/", to: "home#create". I'm trying to make a create method in home_controller.rb.
From the look of it you're calling the method on the User class and not an instance.
If you want to get the issues connected to a user you need to fetch the user first:
User.find(id).issues
If you want to add a record to the association you can use the shovel method or any of the methods generated by the association macro:
User.find(id).issues << Issue.find(3)
User.find(id).issues.push(Issue.find(3))
User.find(id).issue_ids = [1, 2, 3]
Besides that you have a smattering of naming issues in your schema. Use snake_case everywhere in your database schema unless you have a good reason why you want to break the conventions and feel like explicitly configuring table and foreign key names.
I would also really question if you really want to use has_and_belongs_to_many. It should only really be used if you can't foresee that you ever will need to add additional attributes to the join table or never need to query the table directly - it seems pretty unrealistic that that would be true in an issue tracker. You want has_many through: - pretty much always.
I have a route post "/", to: "home#create". I'm trying to make a
create method in home_controller.rb.
Don't throw everything into a junk drawer controller. Think about your app in terms of resources that can be CRUD:ed and create controllers that handle just that resource. You should think about what the relation between a user and an issue is in your domain and how you can model it as an actual entity in the domain logic instead of just plumbing.
Maybe all I need to do is direct you to Rails Guides: Active Record Associations.
There is neither of these
User.issues.find(id)
Issue.users.find(id)
because when you are finding an issue or user by id, you don't use the association. Instead use these:
Issues.find(id)
Users.find(id)
Since the :id is unique this will work and should be what you want.
The only time you want to query issues or users using the association will be when you have the data for the other end of the relationship.
user = User.find(user_id)
issue = user.issues.where(id: issue_id)
Since the :id field is unique, this is the same as Issues.find(id). However if you want to get a collection of a user's issues with some other data, you can put the condition for that data in the where.
You can create an issue for a user this way:
user = User.find(user_id)
issue = User.issues.create( ... )

acts as tenant gem scopes all users data, ignoring scoping data based on the subdomain

I am using acts_as_tenant gem to do a multi-tenant app. I followed the instructions. I am using sub-domains.
In my application_controller.rb I have:
set_current_tenant_by_subdomain(:account, :subdomain)
I am using Account as the tenant. In my User model I called:
acts_as_tenant(:account)
The Problem
When I log into an account using a subdomain (e.g: john.realestate.dev), everything is OK (current_tenant i.e john is set).
I have another model called Property; when the current logged in tenant i.e john creates a new property, that record is seen by all the other users. I want only john to be able see the record he has created.
Where am I going wrong?
my models relationships are:-
Account - has_many :users
User - belongs_to :account
Property
i fixed my issue by creating a relationship between Account(has_many :properties) and Property(Belongs_to :account).
then i added acts_as_tenant(:account) to the Property Model. I ran a migration that adds account_id to the property model.
now it scopes data only created by the logged in user according to the subdomain.
i fixed it by re-reading the gem's doc multiple times until i made sense of this statement from the doc.
acts_as_tenant requires each scoped model to have a column in its schema linking it to a tenant. Adding acts_as_tenant to your model declaration will scope that model to the current tenant BUT ONLY if a current tenant has been set.
Any ideas, suggestions on my implementation are mob welcome.
The real fix here is to make sure you include acts_as_tenant(:account) on every single model you want scoped.
This is going to make sure it checks for the current_tenant before saving data.
You don't necessarily need the has_many and belongs_to relation, although it sounds like it may make sense for your application.

Add 'current_user' to a model. (Devise) Rails

Hi I'm new here and also new in rails.
I want to add a couple values by default to a database called books (Model: Book.erb)
there is a user who creates these books(current_user), and I thought that a way to identify who creates and deletes this content is by adding some default values from the user and clasificate them (to be specific username and password)
my table ":books" has available two fields for adding username and password
I tried to do this:
# Book.erb
class Book < ActiveRecord::Base
after_save :set_default_values
def set_default_values
self.username = current_user.username
self.password = current_user.encrypted_password
end
end
but it seems to be that I can't call 'current_user' from this model.
I was reading a pratice on this blog
but some were saying that this method violates the MVC pattern, do you agree with them?
do you guys know a better way to do this process without violating the pattern?
Well, I'm not sure I can conceive of why you'd want to store a user name and user password in a book table as even if it was easily explained, it would be in violation of normalization practices for good database design which pretty much states you should only express a field once and then share it where it needs to be shared.
Now, assuming you must do this for some reason I can't conceive, I'd have to ask if "username" is your actual field or is it just "name" which is more standard Rails. And, I believe you'll have to have a relationship between these models to pull the data from one into the other and I don't see that book has_many users or one or belongs_to or anything of that sort.
With a relationship between book and user you have access to all user properties without writing them anywhere other than the user table. So I think you probably want to look at that.

Rails 3 - using set_primary_key causes routing Error

I was searching google and stackoverflow for long time, but I can't find the solution of my problem.
Lately, I was using set_primary_key for a table called "employee", because I need to use ther personnel number as my primary key. If I set the code
`set_primary_key :personel_number`
(Personel_number is already a collumn which I want to use as primary key) into my model before I do rake db:migrate and do migrating at last, I come into troubles when I try to fill my database via browser:
`Couldn't find employee with ID=1`
`app/controllers/mitarbeiters_controller.rb:16:in `show'`
Rails searches for employee with ID=1 but it can't find, because I set primary key from personel_number with 601 (e.g.).
Can I do something against it or shall I let Rails create it's own :id first?
It sounds like when the page goes to the controller to create the employee you have a redirect to show the new employee and it is using the default id.

Ruby on Rails working with pre-existing database. Rails makes everything plural

What is the deal with this? I'm working with a pre-existing that I did not do myself. Everything in the database is labeled in singular form. user, security, spec, etc. I guess the right way would be users, securities, specs. At least that's what ruby on rails try's to lookup when I generate a scaffold .
How do I specifically state to use user instead of users in the sql. I don't see anywhere in my project where it is looking up the sql. I mean if my model is user you would think it would try to lookup user. Instead of users.
Thanks for any help.
You need set_table_name :name_of_the_table in your model (source).
So:
class User < ActiveRecord::Base
set_table_name :user
end
The reason they use plural for the table and singular for the model is because an instance of the model represents one user, whereas the table contains all the users. It's just to make it more readable and logical.
You can specifiy the table name:
How do I explicitly specify a Model's table-name mapping in Rails?

Resources